@prosekit/extensions 0.12.2 → 0.14.0

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 (324) hide show
  1. package/dist/{drop-indicator-B1QHFb5m.js → drop-indicator-B_oMfeVP.js} +11 -10
  2. package/dist/drop-indicator-B_oMfeVP.js.map +1 -0
  3. package/dist/{enter-rule-CzWOZF_Z.js → enter-rule-D-p4ykfv.js} +1 -1
  4. package/dist/enter-rule-D-p4ykfv.js.map +1 -0
  5. package/dist/{file-DrfcSid-.js → file-iLVR0eM0.js} +3 -3
  6. package/dist/file-iLVR0eM0.js.map +1 -0
  7. package/dist/{index-oIc1a2f2.d.ts → index-cp1u4e0e.d.ts} +1 -1
  8. package/dist/index-cp1u4e0e.d.ts.map +1 -0
  9. package/dist/{input-rule-dmsb3j6w.js → input-rule-COGr_GBb.js} +1 -1
  10. package/dist/input-rule-COGr_GBb.js.map +1 -0
  11. package/dist/list/style.css +5 -5
  12. package/dist/list/style.css.map +1 -1
  13. package/dist/{mark-rule-BcLB4Uv2.js → mark-rule-CYe8zk4q.js} +6 -6
  14. package/dist/mark-rule-CYe8zk4q.js.map +1 -0
  15. package/dist/{paste-rule-pVb4sqvJ.js → paste-rule-BaDghcaU.js} +7 -7
  16. package/dist/paste-rule-BaDghcaU.js.map +1 -0
  17. package/dist/prosekit-extensions-autocomplete.d.ts +11 -3
  18. package/dist/prosekit-extensions-autocomplete.d.ts.map +1 -1
  19. package/dist/prosekit-extensions-autocomplete.js +171 -60
  20. package/dist/prosekit-extensions-autocomplete.js.map +1 -1
  21. package/dist/prosekit-extensions-background-color.d.ts +62 -0
  22. package/dist/prosekit-extensions-background-color.d.ts.map +1 -0
  23. package/dist/prosekit-extensions-background-color.js +76 -0
  24. package/dist/prosekit-extensions-background-color.js.map +1 -0
  25. package/dist/prosekit-extensions-blockquote.d.ts.map +1 -1
  26. package/dist/prosekit-extensions-blockquote.js +2 -2
  27. package/dist/prosekit-extensions-blockquote.js.map +1 -1
  28. package/dist/prosekit-extensions-bold.d.ts.map +1 -1
  29. package/dist/prosekit-extensions-bold.js +1 -1
  30. package/dist/prosekit-extensions-bold.js.map +1 -1
  31. package/dist/prosekit-extensions-code-block.d.ts +1 -1
  32. package/dist/prosekit-extensions-code-block.d.ts.map +1 -1
  33. package/dist/prosekit-extensions-code-block.js +4 -4
  34. package/dist/prosekit-extensions-code-block.js.map +1 -1
  35. package/dist/prosekit-extensions-code.d.ts.map +1 -1
  36. package/dist/prosekit-extensions-code.js +1 -1
  37. package/dist/prosekit-extensions-code.js.map +1 -1
  38. package/dist/prosekit-extensions-commit.d.ts +0 -1
  39. package/dist/prosekit-extensions-commit.d.ts.map +1 -1
  40. package/dist/prosekit-extensions-commit.js +1 -1
  41. package/dist/prosekit-extensions-commit.js.map +1 -1
  42. package/dist/prosekit-extensions-doc.d.ts +0 -1
  43. package/dist/prosekit-extensions-doc.d.ts.map +1 -1
  44. package/dist/prosekit-extensions-doc.js.map +1 -1
  45. package/dist/prosekit-extensions-drop-cursor.d.ts.map +1 -1
  46. package/dist/prosekit-extensions-drop-cursor.js.map +1 -1
  47. package/dist/prosekit-extensions-drop-indicator.d.ts +0 -1
  48. package/dist/prosekit-extensions-drop-indicator.d.ts.map +1 -1
  49. package/dist/prosekit-extensions-drop-indicator.js +1 -1
  50. package/dist/prosekit-extensions-enter-rule.d.ts +0 -1
  51. package/dist/prosekit-extensions-enter-rule.d.ts.map +1 -1
  52. package/dist/prosekit-extensions-enter-rule.js +1 -1
  53. package/dist/prosekit-extensions-file.d.ts +1 -1
  54. package/dist/prosekit-extensions-file.js +1 -1
  55. package/dist/prosekit-extensions-gap-cursor.d.ts +0 -1
  56. package/dist/prosekit-extensions-gap-cursor.d.ts.map +1 -1
  57. package/dist/prosekit-extensions-gap-cursor.js.map +1 -1
  58. package/dist/prosekit-extensions-hard-break.d.ts.map +1 -1
  59. package/dist/prosekit-extensions-hard-break.js.map +1 -1
  60. package/dist/prosekit-extensions-heading.d.ts.map +1 -1
  61. package/dist/prosekit-extensions-heading.js +7 -7
  62. package/dist/prosekit-extensions-heading.js.map +1 -1
  63. package/dist/prosekit-extensions-horizontal-rule.d.ts.map +1 -1
  64. package/dist/prosekit-extensions-horizontal-rule.js +1 -1
  65. package/dist/prosekit-extensions-horizontal-rule.js.map +1 -1
  66. package/dist/prosekit-extensions-image.d.ts +9 -2
  67. package/dist/prosekit-extensions-image.d.ts.map +1 -1
  68. package/dist/prosekit-extensions-image.js +17 -4
  69. package/dist/prosekit-extensions-image.js.map +1 -1
  70. package/dist/prosekit-extensions-input-rule.d.ts +0 -1
  71. package/dist/prosekit-extensions-input-rule.d.ts.map +1 -1
  72. package/dist/prosekit-extensions-input-rule.js +1 -1
  73. package/dist/prosekit-extensions-italic.d.ts.map +1 -1
  74. package/dist/prosekit-extensions-italic.js +1 -1
  75. package/dist/prosekit-extensions-italic.js.map +1 -1
  76. package/dist/prosekit-extensions-link.d.ts +0 -1
  77. package/dist/prosekit-extensions-link.d.ts.map +1 -1
  78. package/dist/prosekit-extensions-link.js +4 -4
  79. package/dist/prosekit-extensions-link.js.map +1 -1
  80. package/dist/prosekit-extensions-list.d.ts +0 -1
  81. package/dist/prosekit-extensions-list.d.ts.map +1 -1
  82. package/dist/prosekit-extensions-list.js +3 -3
  83. package/dist/prosekit-extensions-list.js.map +1 -1
  84. package/dist/prosekit-extensions-loro.d.ts +16 -17
  85. package/dist/prosekit-extensions-loro.d.ts.map +1 -1
  86. package/dist/prosekit-extensions-loro.js +14 -7
  87. package/dist/prosekit-extensions-loro.js.map +1 -1
  88. package/dist/prosekit-extensions-mark-rule.d.ts +0 -1
  89. package/dist/prosekit-extensions-mark-rule.d.ts.map +1 -1
  90. package/dist/prosekit-extensions-mark-rule.js +1 -1
  91. package/dist/prosekit-extensions-mention.d.ts.map +1 -1
  92. package/dist/prosekit-extensions-mention.js.map +1 -1
  93. package/dist/prosekit-extensions-mod-click-prevention.d.ts +0 -1
  94. package/dist/prosekit-extensions-mod-click-prevention.d.ts.map +1 -1
  95. package/dist/prosekit-extensions-mod-click-prevention.js.map +1 -1
  96. package/dist/prosekit-extensions-paragraph.d.ts.map +1 -1
  97. package/dist/prosekit-extensions-paragraph.js +1 -1
  98. package/dist/prosekit-extensions-paragraph.js.map +1 -1
  99. package/dist/prosekit-extensions-paste-rule.d.ts +0 -1
  100. package/dist/prosekit-extensions-paste-rule.d.ts.map +1 -1
  101. package/dist/prosekit-extensions-paste-rule.js +1 -1
  102. package/dist/prosekit-extensions-placeholder.d.ts.map +1 -1
  103. package/dist/prosekit-extensions-placeholder.js +3 -4
  104. package/dist/prosekit-extensions-placeholder.js.map +1 -1
  105. package/dist/prosekit-extensions-readonly.d.ts +0 -1
  106. package/dist/prosekit-extensions-readonly.d.ts.map +1 -1
  107. package/dist/prosekit-extensions-readonly.js.map +1 -1
  108. package/dist/prosekit-extensions-search.d.ts +0 -1
  109. package/dist/prosekit-extensions-search.d.ts.map +1 -1
  110. package/dist/prosekit-extensions-search.js.map +1 -1
  111. package/dist/prosekit-extensions-strike.d.ts +0 -1
  112. package/dist/prosekit-extensions-strike.d.ts.map +1 -1
  113. package/dist/prosekit-extensions-strike.js +3 -3
  114. package/dist/prosekit-extensions-strike.js.map +1 -1
  115. package/dist/prosekit-extensions-table.d.ts.map +1 -1
  116. package/dist/prosekit-extensions-table.js +1 -2
  117. package/dist/prosekit-extensions-text-align.d.ts +0 -1
  118. package/dist/prosekit-extensions-text-align.d.ts.map +1 -1
  119. package/dist/prosekit-extensions-text-align.js +6 -6
  120. package/dist/prosekit-extensions-text-align.js.map +1 -1
  121. package/dist/prosekit-extensions-text-color.d.ts +62 -0
  122. package/dist/prosekit-extensions-text-color.d.ts.map +1 -0
  123. package/dist/prosekit-extensions-text-color.js +76 -0
  124. package/dist/prosekit-extensions-text-color.js.map +1 -0
  125. package/dist/prosekit-extensions-text.d.ts +0 -1
  126. package/dist/prosekit-extensions-text.d.ts.map +1 -1
  127. package/dist/prosekit-extensions-text.js.map +1 -1
  128. package/dist/prosekit-extensions-underline.d.ts +0 -1
  129. package/dist/prosekit-extensions-underline.d.ts.map +1 -1
  130. package/dist/prosekit-extensions-virtual-selection.d.ts +0 -1
  131. package/dist/prosekit-extensions-virtual-selection.d.ts.map +1 -1
  132. package/dist/prosekit-extensions-virtual-selection.js.map +1 -1
  133. package/dist/prosekit-extensions-yjs.d.ts +9 -2
  134. package/dist/prosekit-extensions-yjs.d.ts.map +1 -1
  135. package/dist/prosekit-extensions-yjs.js +1 -1
  136. package/dist/prosekit-extensions-yjs.js.map +1 -1
  137. package/dist/{shiki-highlighter-chunk-rkzofy4z.d.ts → shiki-highlighter-chunk-DNNm2Vow.d.ts} +1 -1
  138. package/dist/shiki-highlighter-chunk-DNNm2Vow.d.ts.map +1 -0
  139. package/dist/shiki-highlighter-chunk.d.ts +1 -1
  140. package/dist/shiki-highlighter-chunk.js.map +1 -1
  141. package/dist/{table-BRDh_9mG.js → table-4oHfV-Ql.js} +2 -2
  142. package/dist/table-4oHfV-Ql.js.map +1 -0
  143. package/package.json +33 -18
  144. package/src/autocomplete/autocomplete-helpers.ts +19 -14
  145. package/src/autocomplete/autocomplete-plugin.ts +260 -126
  146. package/src/autocomplete/autocomplete-rule.ts +3 -3
  147. package/src/autocomplete/autocomplete.spec.ts +244 -40
  148. package/src/autocomplete/autocomplete.ts +9 -7
  149. package/src/background-color/background-color-commands.spec.ts +71 -0
  150. package/src/background-color/background-color-commands.ts +35 -0
  151. package/src/background-color/background-color-spec.spec.ts +286 -0
  152. package/src/background-color/background-color-spec.ts +58 -0
  153. package/src/background-color/background-color.ts +21 -0
  154. package/src/background-color/index.ts +8 -0
  155. package/src/blockquote/blockquote-commands.ts +1 -7
  156. package/src/blockquote/blockquote-keymap.spec.ts +5 -9
  157. package/src/blockquote/blockquote-keymap.ts +2 -7
  158. package/src/blockquote/blockquote-spec.ts +1 -4
  159. package/src/blockquote/blockquote.ts +3 -12
  160. package/src/blockquote/index.ts +3 -12
  161. package/src/bold/bold-commands.ts +1 -5
  162. package/src/bold/bold-input-rule.spec.ts +1 -5
  163. package/src/bold/bold-input-rule.ts +1 -4
  164. package/src/bold/bold-keymap.ts +1 -5
  165. package/src/bold/bold-spec.ts +1 -4
  166. package/src/bold/bold.ts +3 -12
  167. package/src/bold/index.ts +3 -12
  168. package/src/code/code-commands.ts +1 -5
  169. package/src/code/code-input-rule.ts +1 -4
  170. package/src/code/code-keymap.ts +1 -5
  171. package/src/code/code-spec.ts +1 -4
  172. package/src/code/code.ts +3 -12
  173. package/src/code/index.ts +3 -12
  174. package/src/code-block/code-block-commands.ts +1 -8
  175. package/src/code-block/code-block-highlight.ts +2 -8
  176. package/src/code-block/code-block-keymap.ts +2 -9
  177. package/src/code-block/code-block-shiki.ts +1 -4
  178. package/src/code-block/code-block-spec.spec.ts +4 -11
  179. package/src/code-block/code-block-spec.ts +1 -4
  180. package/src/code-block/code-block.ts +4 -16
  181. package/src/code-block/index.ts +5 -21
  182. package/src/code-block/shiki-highlighter-chunk.ts +1 -7
  183. package/src/code-block/shiki-highlighter.ts +1 -4
  184. package/src/code-block/shiki-parser.ts +1 -4
  185. package/src/commit/index.ts +7 -36
  186. package/src/doc/index.ts +1 -4
  187. package/src/drop-cursor/drop-cursor.ts +1 -4
  188. package/src/drop-cursor/index.ts +1 -5
  189. package/src/drop-indicator/drop-indicator-facet.ts +12 -21
  190. package/src/drop-indicator/index.ts +1 -5
  191. package/src/enter-rule/index.ts +2 -11
  192. package/src/file/file-paste-handler.spec.ts +3 -16
  193. package/src/file/index.ts +3 -16
  194. package/src/gap-cursor/gap-cursor.ts +1 -4
  195. package/src/gap-cursor/index.ts +1 -4
  196. package/src/hard-break/hard-break-commands.ts +1 -5
  197. package/src/hard-break/hard-break-keymap.spec.ts +6 -12
  198. package/src/hard-break/hard-break-keymap.ts +1 -4
  199. package/src/hard-break/hard-break-spec.ts +1 -4
  200. package/src/hard-break/hard-break.ts +3 -12
  201. package/src/hard-break/index.ts +3 -12
  202. package/src/heading/heading-commands.ts +1 -7
  203. package/src/heading/heading-keymap.spec.ts +8 -12
  204. package/src/heading/heading-keymap.ts +7 -14
  205. package/src/heading/heading-spec.ts +1 -4
  206. package/src/heading/heading.ts +3 -12
  207. package/src/heading/index.ts +3 -12
  208. package/src/horizontal-rule/horizontal-rule-commands.spec.ts +1 -5
  209. package/src/horizontal-rule/horizontal-rule-commands.ts +2 -9
  210. package/src/horizontal-rule/horizontal-rule-input-rule.spec.ts +5 -9
  211. package/src/horizontal-rule/horizontal-rule-input-rule.ts +1 -5
  212. package/src/horizontal-rule/horizontal-rule-spec.ts +1 -4
  213. package/src/horizontal-rule/horizontal-rule.ts +3 -12
  214. package/src/horizontal-rule/index.ts +3 -13
  215. package/src/image/image-commands/upload-image.spec.ts +245 -0
  216. package/src/image/image-commands/upload-image.ts +46 -11
  217. package/src/image/image-commands.ts +2 -8
  218. package/src/image/image-spec.ts +1 -4
  219. package/src/image/image-upload-handler.ts +2 -8
  220. package/src/image/image.ts +3 -12
  221. package/src/image/index.ts +3 -13
  222. package/src/input-rule/index.ts +2 -13
  223. package/src/italic/index.ts +3 -12
  224. package/src/italic/italic-commands.spec.ts +2 -10
  225. package/src/italic/italic-commands.ts +1 -5
  226. package/src/italic/italic-input-rule.spec.ts +1 -5
  227. package/src/italic/italic-input-rule.ts +1 -4
  228. package/src/italic/italic-keymap.ts +1 -5
  229. package/src/italic/italic-spec.ts +1 -4
  230. package/src/italic/italic.ts +3 -12
  231. package/src/link/index.spec.ts +10 -13
  232. package/src/link/index.ts +1 -5
  233. package/src/link/link-paste-rule.spec.ts +2 -9
  234. package/src/link/link-regex.spec.ts +1 -5
  235. package/src/list/index.ts +3 -12
  236. package/src/list/list-commands.ts +1 -5
  237. package/src/list/list-input-rules.ts +1 -4
  238. package/src/list/list-keymap.spec.ts +6 -10
  239. package/src/list/list-keymap.ts +2 -8
  240. package/src/list/list-plugins.ts +1 -4
  241. package/src/list/list-serializer.ts +2 -9
  242. package/src/list/list-spec.ts +3 -13
  243. package/src/list/list.spec.ts +10 -21
  244. package/src/list/list.ts +3 -12
  245. package/src/list/style.css +5 -5
  246. package/src/loro/index.ts +3 -13
  247. package/src/loro/loro-commands.ts +2 -8
  248. package/src/loro/loro-cursor-plugin.ts +21 -21
  249. package/src/loro/loro-keymap.ts +3 -11
  250. package/src/loro/loro-sync-plugin.ts +2 -8
  251. package/src/loro/loro-undo-plugin.ts +2 -8
  252. package/src/loro/loro.ts +16 -21
  253. package/src/mark-rule/apply.ts +3 -13
  254. package/src/mark-rule/mark-rule.spec.ts +2 -13
  255. package/src/mark-rule/mark-rule.ts +2 -13
  256. package/src/mark-rule/range.ts +2 -8
  257. package/src/mark-rule/types.ts +1 -4
  258. package/src/mention/index.ts +1 -8
  259. package/src/mod-click-prevention/index.ts +2 -9
  260. package/src/paragraph/paragraph-commands.ts +1 -5
  261. package/src/paragraph/paragraph-keymap.ts +2 -5
  262. package/src/paragraph/paragraph-spec.ts +1 -4
  263. package/src/paragraph/paragraph.ts +3 -14
  264. package/src/paste-rule/index.ts +2 -10
  265. package/src/paste-rule/mark-paste-rule.spec.ts +3 -13
  266. package/src/paste-rule/mark-paste-rule.ts +4 -14
  267. package/src/paste-rule/paste-rule-plugin.ts +2 -11
  268. package/src/paste-rule/paste-rule.spec.ts +4 -19
  269. package/src/paste-rule/split-text-by-regex.spec.ts +1 -5
  270. package/src/placeholder/index.ts +4 -16
  271. package/src/readonly/index.ts +2 -8
  272. package/src/search/index.ts +1 -6
  273. package/src/strike/index.ts +2 -2
  274. package/src/table/index.ts +10 -40
  275. package/src/table/table-commands/delete-cell-selection.spec.ts +1 -5
  276. package/src/table/table-commands/exit-table.spec.ts +1 -5
  277. package/src/table/table-commands/insert-table.spec.ts +1 -5
  278. package/src/table/table-commands/insert-table.ts +1 -4
  279. package/src/table/table-commands/move-table-column.spec.ts +1 -5
  280. package/src/table/table-commands/move-table-column.ts +1 -4
  281. package/src/table/table-commands/move-table-row.spec.ts +1 -5
  282. package/src/table/table-commands/move-table-row.ts +1 -4
  283. package/src/table/table-commands/select-table-cell.spec.ts +1 -5
  284. package/src/table/table-commands/select-table-column.spec.ts +1 -5
  285. package/src/table/table-commands/select-table-row.spec.ts +1 -5
  286. package/src/table/table-commands/select-table.spec.ts +1 -5
  287. package/src/table/table-commands/select-table.ts +1 -4
  288. package/src/table/table-commands.ts +8 -32
  289. package/src/table/table-plugins.ts +2 -8
  290. package/src/table/table-spec.spec.ts +2 -11
  291. package/src/table/table-spec.ts +2 -8
  292. package/src/table/table-utils.ts +2 -6
  293. package/src/table/table.ts +2 -8
  294. package/src/table/test-utils.ts +1 -4
  295. package/src/testing/clipboard.ts +1 -2
  296. package/src/testing/index.ts +9 -14
  297. package/src/testing/keyboard.ts +0 -30
  298. package/src/text/index.ts +1 -4
  299. package/src/text-align/index.ts +6 -6
  300. package/src/text-color/index.ts +3 -0
  301. package/src/text-color/text-color-commands.spec.ts +71 -0
  302. package/src/text-color/text-color-commands.ts +35 -0
  303. package/src/text-color/text-color-spec.spec.ts +297 -0
  304. package/src/text-color/text-color-spec.ts +58 -0
  305. package/src/text-color/text-color.ts +21 -0
  306. package/src/virtual-selection/index.ts +3 -14
  307. package/src/yjs/index.ts +5 -20
  308. package/src/yjs/yjs-commands.ts +2 -8
  309. package/src/yjs/yjs-cursor-plugin.ts +3 -5
  310. package/src/yjs/yjs-keymap.ts +3 -11
  311. package/src/yjs/yjs-sync-plugin.ts +1 -4
  312. package/src/yjs/yjs-types.ts +10 -0
  313. package/src/yjs/yjs-undo-plugin.ts +2 -8
  314. package/src/yjs/yjs.ts +6 -24
  315. package/dist/drop-indicator-B1QHFb5m.js.map +0 -1
  316. package/dist/enter-rule-CzWOZF_Z.js.map +0 -1
  317. package/dist/file-DrfcSid-.js.map +0 -1
  318. package/dist/index-oIc1a2f2.d.ts.map +0 -1
  319. package/dist/input-rule-dmsb3j6w.js.map +0 -1
  320. package/dist/mark-rule-BcLB4Uv2.js.map +0 -1
  321. package/dist/paste-rule-pVb4sqvJ.js.map +0 -1
  322. package/dist/shiki-highlighter-chunk-rkzofy4z.d.ts.map +0 -1
  323. package/dist/table-BRDh_9mG.js.map +0 -1
  324. package/src/testing/format-html.ts +0 -5
@@ -1,21 +1,12 @@
1
1
  import { union } from '@prosekit/core'
2
2
  import pick from 'just-pick'
3
- import {
4
- describe,
5
- expect,
6
- it,
7
- } from 'vitest'
3
+ import { describe, expect, it } from 'vitest'
8
4
 
9
5
  import { defineDoc } from '../doc'
10
6
  import { defineParagraph } from '../paragraph'
11
7
  import { defineText } from '../text'
12
8
 
13
- import {
14
- defineTableCellSpec,
15
- defineTableHeaderCellSpec,
16
- defineTableRowSpec,
17
- defineTableSpec,
18
- } from './table-spec'
9
+ import { defineTableCellSpec, defineTableHeaderCellSpec, defineTableRowSpec, defineTableSpec } from './table-spec'
19
10
 
20
11
  describe('table spec', () => {
21
12
  it('should be defined', () => {
@@ -1,11 +1,5 @@
1
- import {
2
- defineNodeSpec,
3
- type Extension,
4
- } from '@prosekit/core'
5
- import type {
6
- AttributeSpec,
7
- Attrs,
8
- } from '@prosekit/pm/model'
1
+ import { defineNodeSpec, type Extension } from '@prosekit/core'
2
+ import type { AttributeSpec, Attrs } from '@prosekit/pm/model'
9
3
  import { tableNodes } from 'prosemirror-tables'
10
4
 
11
5
  const cellContent = 'block+'
@@ -1,10 +1,6 @@
1
- import { CellSelection } from 'prosemirror-tables'
1
+ import { CellSelection, findCellPos, findCellRange, findTable } from 'prosemirror-tables'
2
2
 
3
- export {
4
- findCellPos,
5
- findCellRange,
6
- findTable,
7
- } from 'prosemirror-tables'
3
+ export { findCellPos, findCellRange, findTable }
8
4
 
9
5
  /**
10
6
  * Checks if the given object is a `CellSelection` instance.
@@ -1,12 +1,6 @@
1
- import {
2
- union,
3
- type Union,
4
- } from '@prosekit/core'
1
+ import { union, type Union } from '@prosekit/core'
5
2
 
6
- import {
7
- defineTableCommands,
8
- type TableCommandsExtension,
9
- } from './table-commands'
3
+ import { defineTableCommands, type TableCommandsExtension } from './table-commands'
10
4
  import { defineTableDropIndicator } from './table-drop-indicator'
11
5
  import { defineTablePlugins } from './table-plugins'
12
6
  import {
@@ -1,7 +1,4 @@
1
- import type {
2
- Command,
3
- Selection,
4
- } from '@prosekit/pm/state'
1
+ import type { Command, Selection } from '@prosekit/pm/state'
5
2
  import { CellSelection } from 'prosemirror-tables'
6
3
 
7
4
  import { isCellSelection } from './table-utils'
@@ -1,6 +1,5 @@
1
1
  import type { EditorView } from '@prosekit/pm/view'
2
-
3
- import { formatHTML } from './format-html'
2
+ import { formatHTML } from 'diffable-html-snapshot'
4
3
 
5
4
  async function readBlobFromClipboard(mimeType: string): Promise<Blob | undefined> {
6
5
  const clipboardItems = await navigator.clipboard.read()
@@ -10,11 +10,10 @@ import {
10
10
  type ExtractNodeActions,
11
11
  type NodeChild,
12
12
  } from '@prosekit/core'
13
- import {
14
- createTestEditor,
15
- type TestEditor,
16
- } from '@prosekit/core/test'
13
+ import { createTestEditor, type TestEditor } from '@prosekit/core/test'
14
+ import { keyboard } from 'vitest-browser-commands/playwright'
17
15
 
16
+ import { defineBackgroundColor } from '../background-color'
18
17
  import { defineBlockquote } from '../blockquote'
19
18
  import { defineBold } from '../bold'
20
19
  import { defineCode } from '../code'
@@ -26,22 +25,16 @@ import { defineHorizontalRule } from '../horizontal-rule'
26
25
  import { defineImage } from '../image'
27
26
  import { defineItalic } from '../italic'
28
27
  import { defineLink } from '../link'
29
- import {
30
- defineList,
31
- type ListAttrs,
32
- } from '../list'
28
+ import { defineList, type ListAttrs } from '../list'
33
29
  import { defineParagraph } from '../paragraph'
34
30
  import { defineStrike } from '../strike'
35
31
  import { defineTable } from '../table'
36
32
  import type { CellAttrs } from '../table/table-spec'
37
33
  import { defineText } from '../text'
34
+ import { defineTextColor } from '../text-color'
38
35
  import { defineUnderline } from '../underline'
39
36
 
40
- import {
41
- readHtmlTextFromClipboard,
42
- readPlainTextFromClipboard,
43
- } from './clipboard'
44
- import { pressKey } from './keyboard'
37
+ import { readHtmlTextFromClipboard, readPlainTextFromClipboard } from './clipboard'
45
38
 
46
39
  /**
47
40
  * @internal
@@ -61,6 +54,8 @@ export function defineTestExtension() {
61
54
  defineUnderline(),
62
55
  defineStrike(),
63
56
  defineCode(),
57
+ defineTextColor(),
58
+ defineBackgroundColor(),
64
59
  defineLink(),
65
60
  defineImage(),
66
61
  defineParagraph(),
@@ -124,7 +119,7 @@ export function setupTest() {
124
119
 
125
120
  const copy = async () => {
126
121
  editor.view.dom.focus()
127
- await pressKey('mod-C')
122
+ await keyboard.press('ControlOrMeta+C')
128
123
  const html = await readHtmlTextFromClipboard()
129
124
  const plain = await readPlainTextFromClipboard()
130
125
  return { html, plain }
@@ -1,35 +1,5 @@
1
- import { isApple } from '@prosekit/core'
2
1
  import { userEvent } from 'vitest/browser'
3
2
 
4
- /**
5
- * @example
6
- *
7
- * ```ts
8
- * await pressKey('mod-1')
9
- * await pressKey('Backspace')
10
- * ```
11
- *
12
- * @internal
13
- */
14
- export async function pressKey(input: string): Promise<void> {
15
- const keys = input.split('-').map((key) => {
16
- if (key.toLowerCase() === 'mod') {
17
- return isApple ? 'Meta' : 'Control'
18
- }
19
- return key
20
- })
21
- const seq: string[] = []
22
- for (const key of keys) {
23
- // Press key without releasing it
24
- seq.push('{' + key + '>}')
25
- }
26
- for (const key of keys.toReversed()) {
27
- // Release a previously pressed key
28
- seq.push('{/' + key + '}')
29
- }
30
- return await userEvent.keyboard(seq.join(''))
31
- }
32
-
33
3
  export async function inputText(input: string): Promise<void> {
34
4
  return await userEvent.keyboard(input)
35
5
  }
package/src/text/index.ts CHANGED
@@ -1,7 +1,4 @@
1
- import {
2
- defineNodeSpec,
3
- type Extension,
4
- } from '@prosekit/core'
1
+ import { defineNodeSpec, type Extension } from '@prosekit/core'
5
2
  import type { Attrs } from '@prosekit/pm/model'
6
3
 
7
4
  /**
@@ -2,7 +2,7 @@ import {
2
2
  defineCommands,
3
3
  defineKeymap,
4
4
  defineNodeAttr,
5
- setNodeAttrs,
5
+ setNodeAttrsBetween,
6
6
  union,
7
7
  type Extension,
8
8
  type PlainExtension,
@@ -74,7 +74,7 @@ export function setTextAlign({
74
74
  types: string[]
75
75
  value: string | null
76
76
  }): Command {
77
- return setNodeAttrs({ type: types, attrs: { textAlign: value } })
77
+ return setNodeAttrsBetween({ type: types, attrs: { textAlign: value } })
78
78
  }
79
79
 
80
80
  /**
@@ -102,10 +102,10 @@ export function defineTextAlignCommands(
102
102
  */
103
103
  export function defineTextAlignKeymap(types: string[]): PlainExtension {
104
104
  return defineKeymap({
105
- 'mod-shift-l': setTextAlign({ types, value: 'left' }),
106
- 'mod-shift-e': setTextAlign({ types, value: 'center' }),
107
- 'mod-shift-r': setTextAlign({ types, value: 'right' }),
108
- 'mod-shift-j': setTextAlign({ types, value: 'justify' }),
105
+ 'Mod-L': setTextAlign({ types, value: 'left' }),
106
+ 'Mod-E': setTextAlign({ types, value: 'center' }),
107
+ 'Mod-R': setTextAlign({ types, value: 'right' }),
108
+ 'Mod-J': setTextAlign({ types, value: 'justify' }),
109
109
  })
110
110
  }
111
111
 
@@ -0,0 +1,3 @@
1
+ export { defineTextColor, type TextColorExtension } from './text-color'
2
+ export { addTextColor, defineTextColorCommands, removeTextColor, type TextColorCommandsExtension } from './text-color-commands'
3
+ export { defineTextColorSpec, type TextColorAttrs, type TextColorSpecExtension } from './text-color-spec'
@@ -0,0 +1,71 @@
1
+ import { describe, expect, it } from 'vitest'
2
+
3
+ import { setupTest } from '../testing'
4
+
5
+ describe('addTextColor', () => {
6
+ it('can add color to text', () => {
7
+ const { editor, n, m } = setupTest()
8
+
9
+ const doc1 = n.doc(
10
+ n.p('Hello <a>world<b>'),
11
+ )
12
+ const doc2 = n.doc(
13
+ n.p('Hello ', m.textColor({ color: 'red' }, 'world')),
14
+ )
15
+
16
+ editor.set(doc1)
17
+ editor.commands.addTextColor({ color: 'red' })
18
+ expect(editor.getDocJSON()).toEqual(doc2.toJSON())
19
+ })
20
+
21
+ it('can override existing color', () => {
22
+ const { editor, n, m } = setupTest()
23
+
24
+ const doc1 = n.doc(
25
+ n.p(
26
+ 'A',
27
+ m.textColor({ color: 'red' }, 'B<a>C'),
28
+ m.textColor({ color: 'red' }, 'DE'),
29
+ 'F<b>G',
30
+ ),
31
+ )
32
+ const doc2 = n.doc(
33
+ n.p(
34
+ 'A',
35
+ m.textColor({ color: 'red' }, 'B'),
36
+ m.textColor({ color: 'blue' }, 'CDEF'),
37
+ 'G',
38
+ ),
39
+ )
40
+
41
+ editor.set(doc1)
42
+ editor.commands.addTextColor({ color: 'blue' })
43
+ expect(editor.getDocJSON()).toEqual(doc2.toJSON())
44
+ })
45
+ })
46
+
47
+ describe('removeColor', () => {
48
+ it('can remove color from text', () => {
49
+ const { editor, n, m } = setupTest()
50
+
51
+ const doc1 = n.doc(
52
+ n.p(
53
+ 'A',
54
+ m.textColor({ color: 'red' }, 'B<a>C'),
55
+ m.textColor({ color: 'blue' }, 'DE'),
56
+ 'F<b>G',
57
+ ),
58
+ )
59
+ const doc2 = n.doc(
60
+ n.p(
61
+ 'A',
62
+ m.textColor({ color: 'red' }, 'B'),
63
+ 'CDEFG',
64
+ ),
65
+ )
66
+
67
+ editor.set(doc1)
68
+ editor.commands.removeTextColor()
69
+ expect(editor.getDocJSON()).toEqual(doc2.toJSON())
70
+ })
71
+ })
@@ -0,0 +1,35 @@
1
+ import { addMark, defineCommands, removeMark, type Extension } from '@prosekit/core'
2
+ import type { Command } from '@prosekit/pm/state'
3
+
4
+ import type { TextColorAttrs } from './text-color-spec'
5
+
6
+ /**
7
+ * @internal
8
+ */
9
+ export function addTextColor(attrs: TextColorAttrs): Command {
10
+ return addMark({ type: 'textColor', attrs })
11
+ }
12
+
13
+ /**
14
+ * @internal
15
+ */
16
+ export function removeTextColor(): Command {
17
+ return removeMark({ type: 'textColor' })
18
+ }
19
+
20
+ /**
21
+ * @internal
22
+ */
23
+ export type TextColorCommandsExtension = Extension<{
24
+ Commands: {
25
+ addTextColor: [attrs: TextColorAttrs]
26
+ removeTextColor: []
27
+ }
28
+ }>
29
+
30
+ /**
31
+ * @internal
32
+ */
33
+ export function defineTextColorCommands(): TextColorCommandsExtension {
34
+ return defineCommands({ addTextColor, removeTextColor })
35
+ }
@@ -0,0 +1,297 @@
1
+ import { formatHTML } from 'diffable-html-snapshot'
2
+ import { describe, expect, it } from 'vitest'
3
+
4
+ import { setupTest } from '../testing'
5
+
6
+ describe('defineTextColorSpec', () => {
7
+ it('should render color as inline span with style attribute', () => {
8
+ const { editor, n, m } = setupTest()
9
+
10
+ const doc = n.doc(
11
+ n.p(
12
+ 'Default',
13
+ m.textColor({ color: '#0000ff' }, 'hex'),
14
+ m.textColor({ color: 'blue' }, 'named'),
15
+ m.textColor({ color: 'rgb(0, 0, 255)' }, 'rgb'),
16
+ m.textColor({ color: 'rgba(0 0 255 / 0.5)' }, 'rgba'),
17
+ m.textColor({ color: 'hsl(240 100% 50% / 0.5)' }, 'hsl'),
18
+ m.textColor({ color: 'var(--color-variable)' }, 'variable'),
19
+ ),
20
+ )
21
+ editor.set(doc)
22
+ expect(formatHTML(editor.view.dom.innerHTML)).toMatchInlineSnapshot(
23
+ `
24
+ "
25
+ <p>
26
+ Default
27
+ <span
28
+ data-text-color="#0000ff"
29
+ style="color: rgb(0, 0, 255);"
30
+ >
31
+ hex
32
+ </span>
33
+ <span
34
+ data-text-color="blue"
35
+ style="color: blue;"
36
+ >
37
+ named
38
+ </span>
39
+ <span
40
+ data-text-color="rgb(0, 0, 255)"
41
+ style="color: rgb(0, 0, 255);"
42
+ >
43
+ rgb
44
+ </span>
45
+ <span
46
+ data-text-color="rgba(0 0 255 / 0.5)"
47
+ style="color: rgba(0, 0, 255, 0.5);"
48
+ >
49
+ rgba
50
+ </span>
51
+ <span
52
+ data-text-color="hsl(240 100% 50% / 0.5)"
53
+ style="color: rgba(0, 0, 255, 0.5);"
54
+ >
55
+ hsl
56
+ </span>
57
+ <span
58
+ data-text-color="var(--color-variable)"
59
+ style="color: var(--color-variable);"
60
+ >
61
+ variable
62
+ </span>
63
+ </p>
64
+ "
65
+ `,
66
+ )
67
+ })
68
+
69
+ it('should parse color from style attribute', () => {
70
+ const { editor } = setupTest()
71
+
72
+ const html = `<p><span style="color: #0000ff;">text</span></p>`
73
+ editor.setContent(html)
74
+ expect(editor.state.doc.firstChild?.firstChild?.toJSON()).toMatchInlineSnapshot(`
75
+ {
76
+ "marks": [
77
+ {
78
+ "attrs": {
79
+ "color": "rgb(0, 0, 255)",
80
+ },
81
+ "type": "textColor",
82
+ },
83
+ ],
84
+ "text": "text",
85
+ "type": "text",
86
+ }
87
+ `)
88
+ })
89
+
90
+ it('should parse color from data-text-color attribute', () => {
91
+ const { editor } = setupTest()
92
+
93
+ const html = `<p><span data-text-color="rgb(0 0 255 / 0.5)">text</span></p>`
94
+ editor.setContent(html)
95
+ expect(editor.state.doc.firstChild?.firstChild?.toJSON()).toMatchInlineSnapshot(`
96
+ {
97
+ "marks": [
98
+ {
99
+ "attrs": {
100
+ "color": "rgb(0 0 255 / 0.5)",
101
+ },
102
+ "type": "textColor",
103
+ },
104
+ ],
105
+ "text": "text",
106
+ "type": "text",
107
+ }
108
+ `)
109
+ })
110
+
111
+ it('should prioritize data-text-color attribute over style attribute', () => {
112
+ const { editor } = setupTest()
113
+
114
+ const html = `<p><span style="color: blue;" data-text-color="red">This should be red</span></p>`
115
+ editor.setContent(html)
116
+ expect(editor.state.doc.firstChild?.firstChild?.toJSON()).toMatchInlineSnapshot(`
117
+ {
118
+ "marks": [
119
+ {
120
+ "attrs": {
121
+ "color": "red",
122
+ },
123
+ "type": "textColor",
124
+ },
125
+ ],
126
+ "text": "This should be red",
127
+ "type": "text",
128
+ }
129
+ `)
130
+ })
131
+
132
+ it('can handle non-span inline elements', () => {
133
+ const { editor } = setupTest()
134
+
135
+ const html = `<p>`
136
+ + `<i><span style="color: red;">This should be red and italic</span></i>`
137
+ + `<span style="color: green;"><i>This should be green and italic</i></span>`
138
+ + `<b style="color: blue;">This should be blue and bold</b>`
139
+ + `</p>`
140
+ editor.setContent(html)
141
+ expect(editor.state.doc.firstChild?.toJSON()).toMatchInlineSnapshot(`
142
+ {
143
+ "content": [
144
+ {
145
+ "marks": [
146
+ {
147
+ "attrs": {
148
+ "color": "red",
149
+ },
150
+ "type": "textColor",
151
+ },
152
+ {
153
+ "type": "italic",
154
+ },
155
+ ],
156
+ "text": "This should be red and italic",
157
+ "type": "text",
158
+ },
159
+ {
160
+ "marks": [
161
+ {
162
+ "attrs": {
163
+ "color": "green",
164
+ },
165
+ "type": "textColor",
166
+ },
167
+ {
168
+ "type": "italic",
169
+ },
170
+ ],
171
+ "text": "This should be green and italic",
172
+ "type": "text",
173
+ },
174
+ {
175
+ "marks": [
176
+ {
177
+ "attrs": {
178
+ "color": "blue",
179
+ },
180
+ "type": "textColor",
181
+ },
182
+ {
183
+ "type": "bold",
184
+ },
185
+ ],
186
+ "text": "This should be blue and bold",
187
+ "type": "text",
188
+ },
189
+ ],
190
+ "type": "paragraph",
191
+ }
192
+ `)
193
+ })
194
+
195
+ it('should ignore empty attributes', () => {
196
+ const { editor } = setupTest()
197
+
198
+ const html = `<p><span data-text-color="" style="color: ;">This should be plain text</span></p>`
199
+ editor.setContent(html)
200
+ expect(editor.state.doc.firstChild?.firstChild?.toJSON()).toMatchInlineSnapshot(`
201
+ {
202
+ "text": "This should be plain text",
203
+ "type": "text",
204
+ }
205
+ `)
206
+ })
207
+
208
+ it('should ignore inherit attributes', () => {
209
+ const { editor } = setupTest()
210
+
211
+ const html = `<p><span data-text-color="inherit" style="color: inherit;">This should be plain text</span></p>`
212
+ editor.setContent(html)
213
+ expect(editor.state.doc.firstChild?.firstChild?.toJSON()).toMatchInlineSnapshot(`
214
+ {
215
+ "text": "This should be plain text",
216
+ "type": "text",
217
+ }
218
+ `)
219
+ })
220
+
221
+ it('can handle block elements', () => {
222
+ const { editor } = setupTest()
223
+
224
+ const html = `<blockquote style="color: red;">`
225
+ + `<p>This should be red</p>`
226
+ + `<blockquote style="color: blue;">`
227
+ + `<p>This should be blue</p>`
228
+ + `</blockquote>`
229
+ + `<p>This should be red again</p>`
230
+ + `</blockquote>`
231
+
232
+ editor.setContent(html)
233
+ expect(editor.state.doc.firstChild?.toJSON()).toMatchInlineSnapshot(`
234
+ {
235
+ "content": [
236
+ {
237
+ "content": [
238
+ {
239
+ "marks": [
240
+ {
241
+ "attrs": {
242
+ "color": "red",
243
+ },
244
+ "type": "textColor",
245
+ },
246
+ ],
247
+ "text": "This should be red",
248
+ "type": "text",
249
+ },
250
+ ],
251
+ "type": "paragraph",
252
+ },
253
+ {
254
+ "content": [
255
+ {
256
+ "content": [
257
+ {
258
+ "marks": [
259
+ {
260
+ "attrs": {
261
+ "color": "blue",
262
+ },
263
+ "type": "textColor",
264
+ },
265
+ ],
266
+ "text": "This should be blue",
267
+ "type": "text",
268
+ },
269
+ ],
270
+ "type": "paragraph",
271
+ },
272
+ ],
273
+ "type": "blockquote",
274
+ },
275
+ {
276
+ "content": [
277
+ {
278
+ "marks": [
279
+ {
280
+ "attrs": {
281
+ "color": "red",
282
+ },
283
+ "type": "textColor",
284
+ },
285
+ ],
286
+ "text": "This should be red again",
287
+ "type": "text",
288
+ },
289
+ ],
290
+ "type": "paragraph",
291
+ },
292
+ ],
293
+ "type": "blockquote",
294
+ }
295
+ `)
296
+ })
297
+ })
@@ -0,0 +1,58 @@
1
+ import { defineMarkSpec, type Extension } from '@prosekit/core'
2
+
3
+ /**
4
+ * Attributes for the `textColor` mark.
5
+ *
6
+ * @public
7
+ */
8
+ export interface TextColorAttrs {
9
+ color: string
10
+ }
11
+
12
+ /**
13
+ * @internal
14
+ */
15
+ export type TextColorSpecExtension = Extension<{
16
+ Marks: {
17
+ textColor: TextColorAttrs
18
+ }
19
+ }>
20
+
21
+ /**
22
+ * @internal
23
+ */
24
+ export function defineTextColorSpec(): TextColorSpecExtension {
25
+ return defineMarkSpec<'textColor', TextColorAttrs>({
26
+ name: 'textColor',
27
+ attrs: {
28
+ color: {
29
+ validate: 'string',
30
+ },
31
+ },
32
+ parseDOM: [
33
+ {
34
+ tag: ':where([style*="color:"], [data-text-color])',
35
+ getAttrs: (node): TextColorAttrs | false => {
36
+ // When both `data-text-color` and `style="color"` are present, we
37
+ // prioritize the `data-text-color` attribute. This avoids the
38
+ // browser's default behavior of changing hex colors to rgba in style
39
+ // attribute.
40
+ const value = node.getAttribute('data-text-color')
41
+ if (value && value !== 'inherit') {
42
+ return { color: value }
43
+ }
44
+ const color = node.style.color
45
+ if (color && color !== 'inherit') {
46
+ return { color }
47
+ }
48
+ return false
49
+ },
50
+ consuming: false,
51
+ },
52
+ ],
53
+ toDOM(mark) {
54
+ const color = (mark.attrs as TextColorAttrs).color
55
+ return ['span', { 'style': `color: ${color};`, 'data-text-color': color }, 0]
56
+ },
57
+ })
58
+ }