@fiduswriter/editor 0.1.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 (525) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +22 -0
  3. package/dist/bibliography/tools.js +53 -0
  4. package/dist/bibliography/tools.js.map +1 -0
  5. package/dist/citations/index.js +339 -0
  6. package/dist/citations/index.js.map +1 -0
  7. package/dist/citations/render.js +47 -0
  8. package/dist/citations/render.js.map +1 -0
  9. package/dist/clipboard/copy/index.js +2 -0
  10. package/dist/clipboard/copy/index.js.map +1 -0
  11. package/dist/clipboard/copy/schema.js +54 -0
  12. package/dist/clipboard/copy/schema.js.map +1 -0
  13. package/dist/clipboard/copy/serializers.js +132 -0
  14. package/dist/clipboard/copy/serializers.js.map +1 -0
  15. package/dist/clipboard/paste/fidus_writer.js +45 -0
  16. package/dist/clipboard/paste/fidus_writer.js.map +1 -0
  17. package/dist/clipboard/paste/general.js +76 -0
  18. package/dist/clipboard/paste/general.js.map +1 -0
  19. package/dist/clipboard/paste/google_docs.js +24 -0
  20. package/dist/clipboard/paste/google_docs.js.map +1 -0
  21. package/dist/clipboard/paste/html.js +68 -0
  22. package/dist/clipboard/paste/html.js.map +1 -0
  23. package/dist/clipboard/paste/index.js +3 -0
  24. package/dist/clipboard/paste/index.js.map +1 -0
  25. package/dist/clipboard/paste/libreoffice_writer.js +27 -0
  26. package/dist/clipboard/paste/libreoffice_writer.js.map +1 -0
  27. package/dist/clipboard/paste/microsoft_word.js +79 -0
  28. package/dist/clipboard/paste/microsoft_word.js.map +1 -0
  29. package/dist/clipboard/paste/text.js +41 -0
  30. package/dist/clipboard/paste/text.js.map +1 -0
  31. package/dist/collab/chat.js +154 -0
  32. package/dist/collab/chat.js.map +1 -0
  33. package/dist/collab/colors.js +62 -0
  34. package/dist/collab/colors.js.map +1 -0
  35. package/dist/collab/doc.js +1090 -0
  36. package/dist/collab/doc.js.map +1 -0
  37. package/dist/collab/index.js +75 -0
  38. package/dist/collab/index.js.map +1 -0
  39. package/dist/collab/merge/changeset.js +90 -0
  40. package/dist/collab/merge/changeset.js.map +1 -0
  41. package/dist/collab/merge/editor.js +708 -0
  42. package/dist/collab/merge/editor.js.map +1 -0
  43. package/dist/collab/merge/footnotes.js +149 -0
  44. package/dist/collab/merge/footnotes.js.map +1 -0
  45. package/dist/collab/merge/index.js +270 -0
  46. package/dist/collab/merge/index.js.map +1 -0
  47. package/dist/collab/merge/recreate_transform.js +259 -0
  48. package/dist/collab/merge/recreate_transform.js.map +1 -0
  49. package/dist/collab/merge/schema.js +117 -0
  50. package/dist/collab/merge/schema.js.map +1 -0
  51. package/dist/collab/merge/state_plugins/action.js +138 -0
  52. package/dist/collab/merge/state_plugins/action.js.map +1 -0
  53. package/dist/collab/merge/state_plugins/clipboard.js +32 -0
  54. package/dist/collab/merge/state_plugins/clipboard.js.map +1 -0
  55. package/dist/collab/merge/state_plugins/diff.js +541 -0
  56. package/dist/collab/merge/state_plugins/diff.js.map +1 -0
  57. package/dist/collab/merge/state_plugins/index.js +3 -0
  58. package/dist/collab/merge/state_plugins/index.js.map +1 -0
  59. package/dist/collab/merge/tools.js +175 -0
  60. package/dist/collab/merge/tools.js.map +1 -0
  61. package/dist/collab/templates.js +10 -0
  62. package/dist/collab/templates.js.map +1 -0
  63. package/dist/comments/comment.js +17 -0
  64. package/dist/comments/comment.js.map +1 -0
  65. package/dist/comments/editors/answer.js +43 -0
  66. package/dist/comments/editors/answer.js.map +1 -0
  67. package/dist/comments/editors/comment.js +278 -0
  68. package/dist/comments/editors/comment.js.map +1 -0
  69. package/dist/comments/editors/index.js +4 -0
  70. package/dist/comments/editors/index.js.map +1 -0
  71. package/dist/comments/editors/notify.js +13 -0
  72. package/dist/comments/editors/notify.js.map +1 -0
  73. package/dist/comments/editors/schema.js +60 -0
  74. package/dist/comments/editors/schema.js.map +1 -0
  75. package/dist/comments/index.js +11 -0
  76. package/dist/comments/index.js.map +1 -0
  77. package/dist/comments/interactions.js +379 -0
  78. package/dist/comments/interactions.js.map +1 -0
  79. package/dist/comments/store.js +438 -0
  80. package/dist/comments/store.js.map +1 -0
  81. package/dist/contacts/add_dialog.js +88 -0
  82. package/dist/contacts/add_dialog.js.map +1 -0
  83. package/dist/contacts/templates.js +23 -0
  84. package/dist/contacts/templates.js.map +1 -0
  85. package/dist/copyright_dialog/index.js +148 -0
  86. package/dist/copyright_dialog/index.js.map +1 -0
  87. package/dist/copyright_dialog/templates.js +48 -0
  88. package/dist/copyright_dialog/templates.js.map +1 -0
  89. package/dist/databases/bibliography.js +162 -0
  90. package/dist/databases/bibliography.js.map +1 -0
  91. package/dist/databases/images.js +260 -0
  92. package/dist/databases/images.js.map +1 -0
  93. package/dist/databases/index.js +55 -0
  94. package/dist/databases/index.js.map +1 -0
  95. package/dist/dialogs/citation.js +321 -0
  96. package/dist/dialogs/citation.js.map +1 -0
  97. package/dist/dialogs/code_block.js +192 -0
  98. package/dist/dialogs/code_block.js.map +1 -0
  99. package/dist/dialogs/contributor.js +132 -0
  100. package/dist/dialogs/contributor.js.map +1 -0
  101. package/dist/dialogs/figure.js +378 -0
  102. package/dist/dialogs/figure.js.map +1 -0
  103. package/dist/dialogs/index.js +11 -0
  104. package/dist/dialogs/index.js.map +1 -0
  105. package/dist/dialogs/language.js +47 -0
  106. package/dist/dialogs/language.js.map +1 -0
  107. package/dist/dialogs/link.js +243 -0
  108. package/dist/dialogs/link.js.map +1 -0
  109. package/dist/dialogs/math.js +121 -0
  110. package/dist/dialogs/math.js.map +1 -0
  111. package/dist/dialogs/ordered_list.js +67 -0
  112. package/dist/dialogs/ordered_list.js.map +1 -0
  113. package/dist/dialogs/revision.js +36 -0
  114. package/dist/dialogs/revision.js.map +1 -0
  115. package/dist/dialogs/subsup.js +109 -0
  116. package/dist/dialogs/subsup.js.map +1 -0
  117. package/dist/dialogs/table.js +217 -0
  118. package/dist/dialogs/table.js.map +1 -0
  119. package/dist/dialogs/templates.js +366 -0
  120. package/dist/dialogs/templates.js.map +1 -0
  121. package/dist/document_template/exporter.js +83 -0
  122. package/dist/document_template/exporter.js.map +1 -0
  123. package/dist/document_template/index.js +327 -0
  124. package/dist/document_template/index.js.map +1 -0
  125. package/dist/documents/access_rights/index.js +532 -0
  126. package/dist/documents/access_rights/index.js.map +1 -0
  127. package/dist/documents/access_rights/templates.js +150 -0
  128. package/dist/documents/access_rights/templates.js.map +1 -0
  129. package/dist/e2ee/encryptor.js +201 -0
  130. package/dist/e2ee/encryptor.js.map +1 -0
  131. package/dist/e2ee/key-manager.js +171 -0
  132. package/dist/e2ee/key-manager.js.map +1 -0
  133. package/dist/e2ee/passphrase-crypto.js +365 -0
  134. package/dist/e2ee/passphrase-crypto.js.map +1 -0
  135. package/dist/e2ee/passphrase-dialog.js +548 -0
  136. package/dist/e2ee/passphrase-dialog.js.map +1 -0
  137. package/dist/e2ee/passphrase-manager.js +350 -0
  138. package/dist/e2ee/passphrase-manager.js.map +1 -0
  139. package/dist/e2ee/password-dialog.js +552 -0
  140. package/dist/e2ee/password-dialog.js.map +1 -0
  141. package/dist/e2ee/snapshot-manager.js +238 -0
  142. package/dist/e2ee/snapshot-manager.js.map +1 -0
  143. package/dist/exporter/native/copy.js +29 -0
  144. package/dist/exporter/native/copy.js.map +1 -0
  145. package/dist/exporter/native/file.js +19 -0
  146. package/dist/exporter/native/file.js.map +1 -0
  147. package/dist/exporter/native/index.js +4 -0
  148. package/dist/exporter/native/index.js.map +1 -0
  149. package/dist/exporter/native/revision.js +54 -0
  150. package/dist/exporter/native/revision.js.map +1 -0
  151. package/dist/exporter/native/zip.js +2 -0
  152. package/dist/exporter/native/zip.js.map +1 -0
  153. package/dist/footnotes/editor.js +180 -0
  154. package/dist/footnotes/editor.js.map +1 -0
  155. package/dist/footnotes/index.js +15 -0
  156. package/dist/footnotes/index.js.map +1 -0
  157. package/dist/footnotes/layout.js +125 -0
  158. package/dist/footnotes/layout.js.map +1 -0
  159. package/dist/footnotes/state_plugins/access_rights.js +25 -0
  160. package/dist/footnotes/state_plugins/access_rights.js.map +1 -0
  161. package/dist/footnotes/state_plugins/index.js +2 -0
  162. package/dist/footnotes/state_plugins/index.js.map +1 -0
  163. package/dist/images/edit_dialog/edit_dialog/index.js +186 -0
  164. package/dist/images/edit_dialog/edit_dialog/index.js.map +1 -0
  165. package/dist/images/edit_dialog/edit_dialog/model.js +152 -0
  166. package/dist/images/edit_dialog/edit_dialog/model.js.map +1 -0
  167. package/dist/images/edit_dialog/edit_dialog/templates.js +33 -0
  168. package/dist/images/edit_dialog/edit_dialog/templates.js.map +1 -0
  169. package/dist/images/edit_dialog/model.js +6 -0
  170. package/dist/images/edit_dialog/model.js.map +1 -0
  171. package/dist/images/selection_dialog/index.js +149 -0
  172. package/dist/images/selection_dialog/index.js.map +1 -0
  173. package/dist/index.js +1002 -0
  174. package/dist/index.js.map +1 -0
  175. package/dist/keymap.js +73 -0
  176. package/dist/keymap.js.map +1 -0
  177. package/dist/marginboxes/index.js +674 -0
  178. package/dist/marginboxes/index.js.map +1 -0
  179. package/dist/marginboxes/templates.js +447 -0
  180. package/dist/marginboxes/templates.js.map +1 -0
  181. package/dist/menus/code_block/index.js +2 -0
  182. package/dist/menus/code_block/index.js.map +1 -0
  183. package/dist/menus/code_block/model.js +49 -0
  184. package/dist/menus/code_block/model.js.map +1 -0
  185. package/dist/menus/figure/index.js +3 -0
  186. package/dist/menus/figure/index.js.map +1 -0
  187. package/dist/menus/figure/model.js +80 -0
  188. package/dist/menus/figure/model.js.map +1 -0
  189. package/dist/menus/figure/utils.js +6 -0
  190. package/dist/menus/figure/utils.js.map +1 -0
  191. package/dist/menus/headerbar/index.js +3 -0
  192. package/dist/menus/headerbar/index.js.map +1 -0
  193. package/dist/menus/headerbar/model.js +743 -0
  194. package/dist/menus/headerbar/model.js.map +1 -0
  195. package/dist/menus/headerbar/view.js +579 -0
  196. package/dist/menus/headerbar/view.js.map +1 -0
  197. package/dist/menus/image/index.js +2 -0
  198. package/dist/menus/image/index.js.map +1 -0
  199. package/dist/menus/image/model.js +32 -0
  200. package/dist/menus/image/model.js.map +1 -0
  201. package/dist/menus/index.js +10 -0
  202. package/dist/menus/index.js.map +1 -0
  203. package/dist/menus/navigator/index.js +2 -0
  204. package/dist/menus/navigator/index.js.map +1 -0
  205. package/dist/menus/navigator/model.js +29 -0
  206. package/dist/menus/navigator/model.js.map +1 -0
  207. package/dist/menus/ordered_list/index.js +2 -0
  208. package/dist/menus/ordered_list/index.js.map +1 -0
  209. package/dist/menus/ordered_list/model.js +17 -0
  210. package/dist/menus/ordered_list/model.js.map +1 -0
  211. package/dist/menus/selection/index.js +3 -0
  212. package/dist/menus/selection/index.js.map +1 -0
  213. package/dist/menus/selection/model.js +108 -0
  214. package/dist/menus/selection/model.js.map +1 -0
  215. package/dist/menus/selection/view.js +125 -0
  216. package/dist/menus/selection/view.js.map +1 -0
  217. package/dist/menus/table/index.js +2 -0
  218. package/dist/menus/table/index.js.map +1 -0
  219. package/dist/menus/table/model.js +319 -0
  220. package/dist/menus/table/model.js.map +1 -0
  221. package/dist/menus/toolbar/index.js +3 -0
  222. package/dist/menus/toolbar/index.js.map +1 -0
  223. package/dist/menus/toolbar/model.js +747 -0
  224. package/dist/menus/toolbar/model.js.map +1 -0
  225. package/dist/menus/toolbar/view.js +314 -0
  226. package/dist/menus/toolbar/view.js.map +1 -0
  227. package/dist/navigator/index.js +435 -0
  228. package/dist/navigator/index.js.map +1 -0
  229. package/dist/no_collab_save/index.js +169 -0
  230. package/dist/no_collab_save/index.js.map +1 -0
  231. package/dist/plugins/citation_dialog/index.js +2 -0
  232. package/dist/plugins/citation_dialog/index.js.map +1 -0
  233. package/dist/plugins/editor/index.js +2 -0
  234. package/dist/plugins/editor/index.js.map +1 -0
  235. package/dist/state_plugins/access_rights.js +30 -0
  236. package/dist/state_plugins/access_rights.js.map +1 -0
  237. package/dist/state_plugins/citation_render.js +78 -0
  238. package/dist/state_plugins/citation_render.js.map +1 -0
  239. package/dist/state_plugins/clipboard.js +217 -0
  240. package/dist/state_plugins/clipboard.js.map +1 -0
  241. package/dist/state_plugins/code_block.js +165 -0
  242. package/dist/state_plugins/code_block.js.map +1 -0
  243. package/dist/state_plugins/collab_carets.js +115 -0
  244. package/dist/state_plugins/collab_carets.js.map +1 -0
  245. package/dist/state_plugins/comments.js +197 -0
  246. package/dist/state_plugins/comments.js.map +1 -0
  247. package/dist/state_plugins/contributor_input/add_button.js +101 -0
  248. package/dist/state_plugins/contributor_input/add_button.js.map +1 -0
  249. package/dist/state_plugins/contributor_input/dropup.js +273 -0
  250. package/dist/state_plugins/contributor_input/dropup.js.map +1 -0
  251. package/dist/state_plugins/contributor_input/helpers.js +23 -0
  252. package/dist/state_plugins/contributor_input/helpers.js.map +1 -0
  253. package/dist/state_plugins/contributor_input/index.js +3 -0
  254. package/dist/state_plugins/contributor_input/index.js.map +1 -0
  255. package/dist/state_plugins/contributor_input/node_view.js +76 -0
  256. package/dist/state_plugins/contributor_input/node_view.js.map +1 -0
  257. package/dist/state_plugins/contributor_input/plugin.js +236 -0
  258. package/dist/state_plugins/contributor_input/plugin.js.map +1 -0
  259. package/dist/state_plugins/document_template.js +213 -0
  260. package/dist/state_plugins/document_template.js.map +1 -0
  261. package/dist/state_plugins/figure.js +90 -0
  262. package/dist/state_plugins/figure.js.map +1 -0
  263. package/dist/state_plugins/footnote_markers.js +187 -0
  264. package/dist/state_plugins/footnote_markers.js.map +1 -0
  265. package/dist/state_plugins/headerbar.js +10 -0
  266. package/dist/state_plugins/headerbar.js.map +1 -0
  267. package/dist/state_plugins/index.js +27 -0
  268. package/dist/state_plugins/index.js.map +1 -0
  269. package/dist/state_plugins/inline_math.js +719 -0
  270. package/dist/state_plugins/inline_math.js.map +1 -0
  271. package/dist/state_plugins/inline_reference/dropup.js +182 -0
  272. package/dist/state_plugins/inline_reference/dropup.js.map +1 -0
  273. package/dist/state_plugins/inline_reference/index.js +2 -0
  274. package/dist/state_plugins/inline_reference/index.js.map +1 -0
  275. package/dist/state_plugins/inline_reference/plugin.js +1134 -0
  276. package/dist/state_plugins/inline_reference/plugin.js.map +1 -0
  277. package/dist/state_plugins/jump_hidden_nodes.js +47 -0
  278. package/dist/state_plugins/jump_hidden_nodes.js.map +1 -0
  279. package/dist/state_plugins/links.js +622 -0
  280. package/dist/state_plugins/links.js.map +1 -0
  281. package/dist/state_plugins/marginboxes.js +13 -0
  282. package/dist/state_plugins/marginboxes.js.map +1 -0
  283. package/dist/state_plugins/ordered_list_menu.js +72 -0
  284. package/dist/state_plugins/ordered_list_menu.js.map +1 -0
  285. package/dist/state_plugins/placeholders.js +98 -0
  286. package/dist/state_plugins/placeholders.js.map +1 -0
  287. package/dist/state_plugins/search.js +212 -0
  288. package/dist/state_plugins/search.js.map +1 -0
  289. package/dist/state_plugins/selection_menu.js +10 -0
  290. package/dist/state_plugins/selection_menu.js.map +1 -0
  291. package/dist/state_plugins/settings.js +191 -0
  292. package/dist/state_plugins/settings.js.map +1 -0
  293. package/dist/state_plugins/table.js +104 -0
  294. package/dist/state_plugins/table.js.map +1 -0
  295. package/dist/state_plugins/tag_input/helpers.js +55 -0
  296. package/dist/state_plugins/tag_input/helpers.js.map +1 -0
  297. package/dist/state_plugins/tag_input/index.js +3 -0
  298. package/dist/state_plugins/tag_input/index.js.map +1 -0
  299. package/dist/state_plugins/tag_input/node_view.js +77 -0
  300. package/dist/state_plugins/tag_input/node_view.js.map +1 -0
  301. package/dist/state_plugins/tag_input/plugin.js +199 -0
  302. package/dist/state_plugins/tag_input/plugin.js.map +1 -0
  303. package/dist/state_plugins/tag_input/tag_editor.js +159 -0
  304. package/dist/state_plugins/tag_input/tag_editor.js.map +1 -0
  305. package/dist/state_plugins/tag_input/tag_editor_plugins.js +61 -0
  306. package/dist/state_plugins/tag_input/tag_editor_plugins.js.map +1 -0
  307. package/dist/state_plugins/toc_render.js +142 -0
  308. package/dist/state_plugins/toc_render.js.map +1 -0
  309. package/dist/state_plugins/toolbar.js +10 -0
  310. package/dist/state_plugins/toolbar.js.map +1 -0
  311. package/dist/state_plugins/track/find_selected_changes.js +82 -0
  312. package/dist/state_plugins/track/find_selected_changes.js.map +1 -0
  313. package/dist/state_plugins/track/helpers.js +67 -0
  314. package/dist/state_plugins/track/helpers.js.map +1 -0
  315. package/dist/state_plugins/track/index.js +3 -0
  316. package/dist/state_plugins/track/index.js.map +1 -0
  317. package/dist/state_plugins/track/plugin.js +114 -0
  318. package/dist/state_plugins/track/plugin.js.map +1 -0
  319. package/dist/tools/index.js +4 -0
  320. package/dist/tools/index.js.map +1 -0
  321. package/dist/tools/key_bindings/index.js +20 -0
  322. package/dist/tools/key_bindings/index.js.map +1 -0
  323. package/dist/tools/key_bindings/templates.js +68 -0
  324. package/dist/tools/key_bindings/templates.js.map +1 -0
  325. package/dist/tools/search_replace/index.js +275 -0
  326. package/dist/tools/search_replace/index.js.map +1 -0
  327. package/dist/tools/search_replace/templates.js +18 -0
  328. package/dist/tools/search_replace/templates.js.map +1 -0
  329. package/dist/tools/word_count/index.js +40 -0
  330. package/dist/tools/word_count/index.js.map +1 -0
  331. package/dist/tools/word_count/templates.js +27 -0
  332. package/dist/tools/word_count/templates.js.map +1 -0
  333. package/dist/track/accept.js +66 -0
  334. package/dist/track/accept.js.map +1 -0
  335. package/dist/track/accept_all.js +51 -0
  336. package/dist/track/accept_all.js.map +1 -0
  337. package/dist/track/accept_all_no_insertions.js +63 -0
  338. package/dist/track/accept_all_no_insertions.js.map +1 -0
  339. package/dist/track/amend_transaction.js +390 -0
  340. package/dist/track/amend_transaction.js.map +1 -0
  341. package/dist/track/delete.js +62 -0
  342. package/dist/track/delete.js.map +1 -0
  343. package/dist/track/index.js +6 -0
  344. package/dist/track/index.js.map +1 -0
  345. package/dist/track/mod.js +86 -0
  346. package/dist/track/mod.js.map +1 -0
  347. package/dist/track/reject.js +67 -0
  348. package/dist/track/reject.js.map +1 -0
  349. package/dist/track/reject_all.js +56 -0
  350. package/dist/track/reject_all.js.map +1 -0
  351. package/package.json +80 -0
  352. package/src/bibliography/tools.js +58 -0
  353. package/src/citations/index.js +443 -0
  354. package/src/citations/render.js +68 -0
  355. package/src/clipboard/copy/index.js +1 -0
  356. package/src/clipboard/copy/schema.js +62 -0
  357. package/src/clipboard/copy/serializers.js +179 -0
  358. package/src/clipboard/paste/fidus_writer.js +55 -0
  359. package/src/clipboard/paste/general.js +80 -0
  360. package/src/clipboard/paste/google_docs.js +26 -0
  361. package/src/clipboard/paste/html.js +76 -0
  362. package/src/clipboard/paste/index.js +2 -0
  363. package/src/clipboard/paste/libreoffice_writer.js +32 -0
  364. package/src/clipboard/paste/microsoft_word.js +87 -0
  365. package/src/clipboard/paste/text.js +58 -0
  366. package/src/collab/chat.js +195 -0
  367. package/src/collab/colors.js +67 -0
  368. package/src/collab/doc.js +1436 -0
  369. package/src/collab/index.js +81 -0
  370. package/src/collab/merge/changeset.js +103 -0
  371. package/src/collab/merge/editor.js +1065 -0
  372. package/src/collab/merge/footnotes.js +175 -0
  373. package/src/collab/merge/index.js +401 -0
  374. package/src/collab/merge/recreate_transform.js +326 -0
  375. package/src/collab/merge/schema.js +135 -0
  376. package/src/collab/merge/state_plugins/action.js +171 -0
  377. package/src/collab/merge/state_plugins/clipboard.js +32 -0
  378. package/src/collab/merge/state_plugins/diff.js +780 -0
  379. package/src/collab/merge/state_plugins/index.js +2 -0
  380. package/src/collab/merge/tools.js +217 -0
  381. package/src/collab/templates.js +10 -0
  382. package/src/comments/comment.js +29 -0
  383. package/src/comments/editors/answer.js +55 -0
  384. package/src/comments/editors/comment.js +318 -0
  385. package/src/comments/editors/index.js +4 -0
  386. package/src/comments/editors/notify.js +13 -0
  387. package/src/comments/editors/schema.js +65 -0
  388. package/src/comments/index.js +11 -0
  389. package/src/comments/interactions.js +465 -0
  390. package/src/comments/store.js +513 -0
  391. package/src/contacts/add_dialog.js +110 -0
  392. package/src/contacts/templates.js +28 -0
  393. package/src/copyright_dialog/index.js +179 -0
  394. package/src/copyright_dialog/templates.js +56 -0
  395. package/src/databases/bibliography.js +179 -0
  396. package/src/databases/images.js +320 -0
  397. package/src/databases/index.js +69 -0
  398. package/src/dialogs/citation.js +428 -0
  399. package/src/dialogs/code_block.js +242 -0
  400. package/src/dialogs/contributor.js +173 -0
  401. package/src/dialogs/figure.js +479 -0
  402. package/src/dialogs/index.js +10 -0
  403. package/src/dialogs/language.js +58 -0
  404. package/src/dialogs/link.js +358 -0
  405. package/src/dialogs/math.js +148 -0
  406. package/src/dialogs/ordered_list.js +84 -0
  407. package/src/dialogs/revision.js +43 -0
  408. package/src/dialogs/subsup.js +116 -0
  409. package/src/dialogs/table.js +258 -0
  410. package/src/dialogs/templates.js +426 -0
  411. package/src/document_template/exporter.js +97 -0
  412. package/src/document_template/index.js +483 -0
  413. package/src/documents/access_rights/index.js +693 -0
  414. package/src/documents/access_rights/templates.js +178 -0
  415. package/src/e2ee/encryptor.js +228 -0
  416. package/src/e2ee/key-manager.js +202 -0
  417. package/src/e2ee/passphrase-crypto.js +606 -0
  418. package/src/e2ee/passphrase-dialog.js +655 -0
  419. package/src/e2ee/passphrase-manager.js +502 -0
  420. package/src/e2ee/password-dialog.js +652 -0
  421. package/src/e2ee/snapshot-manager.js +305 -0
  422. package/src/exporter/native/copy.js +54 -0
  423. package/src/exporter/native/file.js +37 -0
  424. package/src/exporter/native/index.js +3 -0
  425. package/src/exporter/native/revision.js +86 -0
  426. package/src/exporter/native/zip.js +1 -0
  427. package/src/footnotes/editor.js +227 -0
  428. package/src/footnotes/index.js +16 -0
  429. package/src/footnotes/layout.js +190 -0
  430. package/src/footnotes/state_plugins/access_rights.js +39 -0
  431. package/src/footnotes/state_plugins/index.js +1 -0
  432. package/src/images/edit_dialog/edit_dialog/index.js +222 -0
  433. package/src/images/edit_dialog/edit_dialog/model.js +183 -0
  434. package/src/images/edit_dialog/edit_dialog/templates.js +41 -0
  435. package/src/images/edit_dialog/model.js +5 -0
  436. package/src/images/selection_dialog/index.js +176 -0
  437. package/src/index.js +1252 -0
  438. package/src/keymap.js +102 -0
  439. package/src/marginboxes/index.js +946 -0
  440. package/src/marginboxes/templates.js +573 -0
  441. package/src/menus/code_block/index.js +1 -0
  442. package/src/menus/code_block/model.js +52 -0
  443. package/src/menus/figure/index.js +2 -0
  444. package/src/menus/figure/model.js +91 -0
  445. package/src/menus/figure/utils.js +5 -0
  446. package/src/menus/headerbar/index.js +2 -0
  447. package/src/menus/headerbar/model.js +1077 -0
  448. package/src/menus/headerbar/view.js +675 -0
  449. package/src/menus/image/index.js +1 -0
  450. package/src/menus/image/model.js +32 -0
  451. package/src/menus/index.js +9 -0
  452. package/src/menus/navigator/index.js +1 -0
  453. package/src/menus/navigator/model.js +28 -0
  454. package/src/menus/ordered_list/index.js +1 -0
  455. package/src/menus/ordered_list/model.js +19 -0
  456. package/src/menus/selection/index.js +2 -0
  457. package/src/menus/selection/model.js +134 -0
  458. package/src/menus/selection/view.js +154 -0
  459. package/src/menus/table/index.js +1 -0
  460. package/src/menus/table/model.js +414 -0
  461. package/src/menus/toolbar/index.js +2 -0
  462. package/src/menus/toolbar/model.js +920 -0
  463. package/src/menus/toolbar/view.js +354 -0
  464. package/src/navigator/index.js +515 -0
  465. package/src/no_collab_save/index.js +209 -0
  466. package/src/plugins/citation_dialog/index.js +1 -0
  467. package/src/plugins/editor/index.js +1 -0
  468. package/src/state_plugins/access_rights.js +47 -0
  469. package/src/state_plugins/citation_render.js +88 -0
  470. package/src/state_plugins/clipboard.js +289 -0
  471. package/src/state_plugins/code_block.js +201 -0
  472. package/src/state_plugins/collab_carets.js +152 -0
  473. package/src/state_plugins/comments.js +259 -0
  474. package/src/state_plugins/contributor_input/add_button.js +134 -0
  475. package/src/state_plugins/contributor_input/dropup.js +318 -0
  476. package/src/state_plugins/contributor_input/helpers.js +24 -0
  477. package/src/state_plugins/contributor_input/index.js +2 -0
  478. package/src/state_plugins/contributor_input/node_view.js +86 -0
  479. package/src/state_plugins/contributor_input/plugin.js +318 -0
  480. package/src/state_plugins/document_template.js +315 -0
  481. package/src/state_plugins/figure.js +108 -0
  482. package/src/state_plugins/footnote_markers.js +238 -0
  483. package/src/state_plugins/headerbar.js +12 -0
  484. package/src/state_plugins/index.js +73 -0
  485. package/src/state_plugins/inline_math.js +918 -0
  486. package/src/state_plugins/inline_reference/dropup.js +208 -0
  487. package/src/state_plugins/inline_reference/index.js +5 -0
  488. package/src/state_plugins/inline_reference/plugin.js +1429 -0
  489. package/src/state_plugins/jump_hidden_nodes.js +58 -0
  490. package/src/state_plugins/links.js +830 -0
  491. package/src/state_plugins/marginboxes.js +14 -0
  492. package/src/state_plugins/ordered_list_menu.js +84 -0
  493. package/src/state_plugins/placeholders.js +123 -0
  494. package/src/state_plugins/search.js +251 -0
  495. package/src/state_plugins/selection_menu.js +12 -0
  496. package/src/state_plugins/settings.js +223 -0
  497. package/src/state_plugins/table.js +127 -0
  498. package/src/state_plugins/tag_input/helpers.js +69 -0
  499. package/src/state_plugins/tag_input/index.js +2 -0
  500. package/src/state_plugins/tag_input/node_view.js +85 -0
  501. package/src/state_plugins/tag_input/plugin.js +278 -0
  502. package/src/state_plugins/tag_input/tag_editor.js +202 -0
  503. package/src/state_plugins/tag_input/tag_editor_plugins.js +74 -0
  504. package/src/state_plugins/toc_render.js +160 -0
  505. package/src/state_plugins/toolbar.js +12 -0
  506. package/src/state_plugins/track/find_selected_changes.js +107 -0
  507. package/src/state_plugins/track/helpers.js +108 -0
  508. package/src/state_plugins/track/index.js +6 -0
  509. package/src/state_plugins/track/plugin.js +140 -0
  510. package/src/tools/index.js +3 -0
  511. package/src/tools/key_bindings/index.js +21 -0
  512. package/src/tools/key_bindings/templates.js +68 -0
  513. package/src/tools/search_replace/index.js +421 -0
  514. package/src/tools/search_replace/templates.js +19 -0
  515. package/src/tools/word_count/index.js +59 -0
  516. package/src/tools/word_count/templates.js +34 -0
  517. package/src/track/accept.js +102 -0
  518. package/src/track/accept_all.js +103 -0
  519. package/src/track/accept_all_no_insertions.js +102 -0
  520. package/src/track/amend_transaction.js +562 -0
  521. package/src/track/delete.js +92 -0
  522. package/src/track/index.js +8 -0
  523. package/src/track/mod.js +116 -0
  524. package/src/track/reject.js +116 -0
  525. package/src/track/reject_all.js +121 -0
@@ -0,0 +1,918 @@
1
+ import {
2
+ NodeSelection,
3
+ Plugin,
4
+ PluginKey,
5
+ TextSelection
6
+ } from "prosemirror-state"
7
+ import {Decoration, DecorationSet} from "prosemirror-view"
8
+
9
+ import {COMMENT_ONLY_ROLES, READ_ONLY_ROLES} from ".."
10
+ import {MathDialog} from "../dialogs"
11
+ import {elementDisabled} from "../menus/toolbar/model"
12
+
13
+ const key = new PluginKey("inlineMath")
14
+
15
+ /**
16
+ * Check if an inline equation can be activated at the current position.
17
+ * Mirrors the toolbar equation-button disabled check.
18
+ */
19
+ function canActivateInlineMath(_state, _$pos, editor) {
20
+ if (editor && elementDisabled(editor, "equation")) {
21
+ return false
22
+ }
23
+ return true
24
+ }
25
+
26
+ /* ────────────────────────────────────────────────────────── */
27
+ /* Helpers shared by the inline-editor widget */
28
+ /* ────────────────────────────────────────────────────────── */
29
+
30
+ function getInputCursorPos(input) {
31
+ const sel = window.getSelection()
32
+ if (!sel || sel.rangeCount === 0) {
33
+ return (input.textContent || "").length
34
+ }
35
+ return sel.getRangeAt(0).startOffset
36
+ }
37
+
38
+ function setInputCursorPos(input, pos) {
39
+ const textNode = input.firstChild
40
+ if (!textNode) {
41
+ return
42
+ }
43
+ const range = document.createRange()
44
+ const safePos = Math.min(pos, (textNode.textContent || "").length)
45
+ range.setStart(textNode, safePos)
46
+ range.collapse(true)
47
+ const sel = window.getSelection()
48
+ if (sel) {
49
+ sel.removeAllRanges()
50
+ sel.addRange(range)
51
+ }
52
+ }
53
+
54
+ /**
55
+ * Build the contenteditable widget that lets the user type raw LaTeX.
56
+ * The query includes the leading "$", which is shown in the widget so the
57
+ * user always sees "$…latex…".
58
+ */
59
+ function createInlineMathWidget(editor, pluginState, pluginKey) {
60
+ const view = editor.currentView || editor.view
61
+ const container = document.createElement("span")
62
+ container.className = "inline-math-widget"
63
+
64
+ const input = document.createElement("span")
65
+ input.contentEditable = "plaintext-only"
66
+ input.spellcheck = false
67
+ input.className = "inline-math-input"
68
+ input.textContent = pluginState.query
69
+
70
+ input.addEventListener("input", event => {
71
+ event.stopPropagation()
72
+ const text = input.textContent || ""
73
+ if (!text) {
74
+ // Everything including `$` was deleted — remove the node.
75
+ view.dispatch(
76
+ view.state.tr.setMeta(pluginKey, {action: "cancelDelete"})
77
+ )
78
+ view.focus()
79
+ return
80
+ }
81
+ if (!text.startsWith("$")) {
82
+ // `$` was removed but content remains — restore it.
83
+ const cursorPos = getInputCursorPos(input)
84
+ input.textContent = "$" + text
85
+ setInputCursorPos(input, cursorPos + 1)
86
+ }
87
+ view.dispatch(
88
+ view.state.tr.setMeta(pluginKey, {
89
+ action: "updateQuery",
90
+ query: input.textContent
91
+ })
92
+ )
93
+ })
94
+
95
+ input.addEventListener("keypress", event => {
96
+ // Stop keypress from reaching ProseMirror
97
+ event.stopPropagation()
98
+ })
99
+
100
+ input.addEventListener("keydown", event => {
101
+ event.stopPropagation()
102
+ const currentState = pluginKey.getState(view.state)
103
+ if (!currentState?.active) {
104
+ return
105
+ }
106
+ switch (event.key) {
107
+ case "ArrowLeft":
108
+ if (getInputCursorPos(input) === 0) {
109
+ event.preventDefault()
110
+ view.dispatch(
111
+ view.state.tr.setMeta(pluginKey, {action: "cancelLeft"})
112
+ )
113
+ view.focus()
114
+ }
115
+ break
116
+ case "ArrowRight":
117
+ if (
118
+ getInputCursorPos(input) ===
119
+ (input.textContent || "").length
120
+ ) {
121
+ event.preventDefault()
122
+ view.dispatch(
123
+ view.state.tr.setMeta(pluginKey, {
124
+ action: "commitAndRight"
125
+ })
126
+ )
127
+ view.focus()
128
+ }
129
+ break
130
+ case "Enter":
131
+ case "Tab":
132
+ event.preventDefault()
133
+ view.dispatch(
134
+ view.state.tr.setMeta(pluginKey, {action: "commit"})
135
+ )
136
+ view.focus()
137
+ break
138
+ case "Escape":
139
+ event.preventDefault()
140
+ view.dispatch(
141
+ view.state.tr.setMeta(pluginKey, {action: "cancel"})
142
+ )
143
+ view.focus()
144
+ break
145
+ case "Backspace":
146
+ // When only `$` remains, delete the whole node.
147
+ if ((input.textContent || "").length <= 1) {
148
+ event.preventDefault()
149
+ view.dispatch(
150
+ view.state.tr.setMeta(pluginKey, {
151
+ action: "cancelDelete"
152
+ })
153
+ )
154
+ view.focus()
155
+ }
156
+ break
157
+ case "Delete":
158
+ // Same as Backspace when only `$` is left.
159
+ if ((input.textContent || "").length <= 1) {
160
+ event.preventDefault()
161
+ view.dispatch(
162
+ view.state.tr.setMeta(pluginKey, {
163
+ action: "cancelDelete"
164
+ })
165
+ )
166
+ view.focus()
167
+ }
168
+ break
169
+ default:
170
+ break
171
+ }
172
+ })
173
+
174
+ input.addEventListener("focusout", event => {
175
+ const related = event.relatedTarget
176
+ if (container.contains(related)) {
177
+ return
178
+ }
179
+ const myWidgetId = pluginState.widgetId
180
+ // Use a tiny timeout so that a click on the container itself
181
+ // (e.g. scrollbar) does not accidentally commit.
182
+ setTimeout(() => {
183
+ const currentState = pluginKey.getState(view.state)
184
+ if (currentState?.active && currentState.widgetId === myWidgetId) {
185
+ view.dispatch(
186
+ view.state.tr.setMeta(pluginKey, {action: "commit"})
187
+ )
188
+ }
189
+ }, 1)
190
+ })
191
+
192
+ container.addEventListener("mousedown", event => {
193
+ event.stopPropagation()
194
+ })
195
+
196
+ container.appendChild(input)
197
+
198
+ // Focus the input and position the cursor after mounting.
199
+ setTimeout(() => {
200
+ input.focus()
201
+ if (pluginState.cursorAtStart === true) {
202
+ setInputCursorPos(input, 0)
203
+ } else {
204
+ setInputCursorPos(input, (input.textContent || "").length)
205
+ }
206
+ }, 0)
207
+
208
+ return container
209
+ }
210
+
211
+ /* ────────────────────────────────────────────────────────── */
212
+ /* Dropup plugin (inline_math preference OFF) */
213
+ /* ────────────────────────────────────────────────────────── */
214
+
215
+ function dropupPlugin(options) {
216
+ const editor = options.editor
217
+ let currentDropUpActions = []
218
+
219
+ const editAccess = ["write", "write-tracked", "review-tracked"].includes(
220
+ editor.docInfo.access_rights
221
+ )
222
+
223
+ function getEquationNode(state) {
224
+ return state.selection instanceof NodeSelection &&
225
+ state.selection.node.type.name === "equation"
226
+ ? state.selection.node
227
+ : undefined
228
+ }
229
+
230
+ function createEquationDropUp(equationNode, selectedIndex = -1) {
231
+ const dropUp = document.createElement("span")
232
+ dropUp.classList.add("drop-up-outer")
233
+
234
+ const _latex = equationNode.attrs.equation || ""
235
+ const requiredPx = editAccess ? 92 : 50
236
+
237
+ dropUp.innerHTML = `
238
+ <div class="drop-up-inner" style="top: -${requiredPx}px;">
239
+ <div class="drop-up-head"${editAccess ? "" : ' style="border-radius:6px;"'}>
240
+ <div class="link-title">${gettext("Equation")}</div>
241
+ </div>
242
+ ${
243
+ editAccess
244
+ ? `<ul class="drop-up-options">
245
+ <li class="edit-equation" title="${gettext("Edit equation")}">
246
+ ${gettext("Edit")}
247
+ </li>
248
+ <li class="remove-equation" title="${gettext("Remove equation")}">
249
+ ${gettext("Remove")}
250
+ </li>
251
+ </ul>`
252
+ : ""
253
+ }
254
+ </div>`
255
+
256
+ currentDropUpActions = []
257
+ const setupAction = (selector, action) => {
258
+ const el = dropUp.querySelector(selector)
259
+ if (!el) {
260
+ return
261
+ }
262
+ currentDropUpActions.push(action)
263
+ el.addEventListener("mousedown", event => {
264
+ event.preventDefault()
265
+ event.stopImmediatePropagation()
266
+ action()
267
+ })
268
+ }
269
+
270
+ setupAction(".edit-equation", () => {
271
+ // MathDialog reads the NodeSelection from the view, so we rely on
272
+ // the equation node already being NodeSelected when the button is
273
+ // activated.
274
+ const dialog = new MathDialog(editor)
275
+ dialog.init()
276
+ })
277
+
278
+ setupAction(".remove-equation", () => {
279
+ const view = editor.currentView
280
+ const state = view.state
281
+ if (state.selection instanceof NodeSelection) {
282
+ view.dispatch(state.tr.deleteSelection())
283
+ }
284
+ })
285
+
286
+ if (selectedIndex >= 0 && selectedIndex < currentDropUpActions.length) {
287
+ const items = Array.from(
288
+ dropUp.querySelectorAll(".drop-up-options li")
289
+ )
290
+ if (items[selectedIndex]) {
291
+ items[selectedIndex].classList.add("fw-focused")
292
+ }
293
+ }
294
+
295
+ return dropUp
296
+ }
297
+
298
+ function getDecos(state, selectedIndex = -1) {
299
+ const equationNode = getEquationNode(state)
300
+ if (!equationNode) {
301
+ return DecorationSet.empty
302
+ }
303
+ // Place the dropup widget just after the equation node.
304
+ const startPos = state.selection.from + equationNode.nodeSize
305
+ const dom = createEquationDropUp(equationNode, selectedIndex)
306
+ return DecorationSet.create(state.doc, [
307
+ Decoration.widget(startPos, dom)
308
+ ])
309
+ }
310
+
311
+ return new Plugin({
312
+ key,
313
+ state: {
314
+ init() {
315
+ return {
316
+ equationNode: undefined,
317
+ decos: DecorationSet.empty,
318
+ selectedIndex: -1
319
+ }
320
+ },
321
+ apply(tr, prev, _oldState, state) {
322
+ const newEquationNode = getEquationNode(state)
323
+ const meta = tr.getMeta(key)
324
+ let {selectedIndex} = prev
325
+
326
+ if (meta?.action === "navigate") {
327
+ selectedIndex = meta.index
328
+ return {
329
+ equationNode: newEquationNode,
330
+ decos: getDecos(state, selectedIndex),
331
+ selectedIndex
332
+ }
333
+ }
334
+
335
+ if (newEquationNode === prev.equationNode) {
336
+ return {
337
+ equationNode: newEquationNode,
338
+ decos: prev.decos.map(tr.mapping, tr.doc),
339
+ selectedIndex
340
+ }
341
+ }
342
+
343
+ // Equation node changed (or deselected): reset selection index.
344
+ selectedIndex = -1
345
+ return {
346
+ equationNode: newEquationNode,
347
+ decos: getDecos(state, selectedIndex),
348
+ selectedIndex
349
+ }
350
+ }
351
+ },
352
+ props: {
353
+ handleKeyDown(view, event) {
354
+ const pluginState = key.getState(view.state)
355
+ if (!pluginState?.equationNode) {
356
+ return false
357
+ }
358
+ const totalItems = currentDropUpActions.length
359
+ if (totalItems === 0) {
360
+ return false
361
+ }
362
+ const {selectedIndex} = pluginState
363
+
364
+ if (event.key === "ArrowDown") {
365
+ event.preventDefault()
366
+ const newIndex =
367
+ selectedIndex < totalItems - 1 ? selectedIndex + 1 : 0
368
+ view.dispatch(
369
+ view.state.tr.setMeta(key, {
370
+ action: "navigate",
371
+ index: newIndex
372
+ })
373
+ )
374
+ return true
375
+ }
376
+ if (event.key === "ArrowUp") {
377
+ event.preventDefault()
378
+ const newIndex =
379
+ selectedIndex <= 0 ? totalItems - 1 : selectedIndex - 1
380
+ view.dispatch(
381
+ view.state.tr.setMeta(key, {
382
+ action: "navigate",
383
+ index: newIndex
384
+ })
385
+ )
386
+ return true
387
+ }
388
+ if (
389
+ event.key === "Enter" &&
390
+ selectedIndex >= 0 &&
391
+ selectedIndex < totalItems
392
+ ) {
393
+ event.preventDefault()
394
+ currentDropUpActions[selectedIndex]()
395
+ return true
396
+ }
397
+ return false
398
+ },
399
+ decorations(state) {
400
+ const pluginState = key.getState(state)
401
+ return pluginState?.decos || DecorationSet.empty
402
+ }
403
+ }
404
+ })
405
+ }
406
+
407
+ /* ────────────────────────────────────────────────────────── */
408
+ /* Inline editor plugin (inline_math preference ON) */
409
+ /* ────────────────────────────────────────────────────────── */
410
+
411
+ function inlineEditorPlugin(options) {
412
+ const editor = options.editor
413
+
414
+ return new Plugin({
415
+ key,
416
+ state: {
417
+ init() {
418
+ return {
419
+ active: false,
420
+ from: 0,
421
+ query: "",
422
+ isEdit: false,
423
+ mathNodePos: 0,
424
+ widgetId: undefined,
425
+ cursorAtStart: undefined,
426
+ decos: DecorationSet.empty
427
+ }
428
+ },
429
+ apply(tr, prev, _oldState, _newState) {
430
+ let next = {...prev}
431
+ const meta = tr.getMeta(key)
432
+
433
+ if (meta?.action === "activate") {
434
+ next = {
435
+ active: true,
436
+ from: meta.from,
437
+ query: meta.query || "$",
438
+ isEdit: meta.isEdit || false,
439
+ mathNodePos: meta.mathNodePos || 0,
440
+ widgetId: Math.random().toString(36).slice(2),
441
+ cursorAtStart: meta.cursorAtStart,
442
+ decos: DecorationSet.empty
443
+ }
444
+ } else if (meta?.action === "deactivate") {
445
+ next = {
446
+ active: false,
447
+ from: 0,
448
+ query: "",
449
+ isEdit: false,
450
+ mathNodePos: 0,
451
+ widgetId: undefined,
452
+ cursorAtStart: undefined,
453
+ decos: DecorationSet.empty
454
+ }
455
+ } else if (meta?.action === "updateQuery") {
456
+ next.query = meta.query
457
+ }
458
+
459
+ if (next.active) {
460
+ if (!prev.active || prev.from !== next.from) {
461
+ // Position changed or freshly activated: build decorations.
462
+ const decoList = [
463
+ Decoration.widget(
464
+ next.from,
465
+ () => createInlineMathWidget(editor, next, key),
466
+ {key: "inline-math-widget", side: -1}
467
+ )
468
+ ]
469
+ if (next.isEdit) {
470
+ // Hide the equation node while the inline editor is open.
471
+ decoList.push(
472
+ Decoration.node(
473
+ next.mathNodePos,
474
+ next.mathNodePos + 1,
475
+ {class: "hide"}
476
+ )
477
+ )
478
+ }
479
+ next.decos = DecorationSet.create(
480
+ _newState.doc,
481
+ decoList
482
+ )
483
+ } else if (tr.docChanged) {
484
+ next.decos = prev.decos.map(tr.mapping, _newState.doc)
485
+ } else {
486
+ next.decos = prev.decos
487
+ }
488
+ } else {
489
+ next.decos = DecorationSet.empty
490
+ }
491
+
492
+ return next
493
+ }
494
+ },
495
+
496
+ appendTransaction: (trs, oldState, newState) => {
497
+ const oldPluginState = key.getState(oldState)
498
+ const meta = trs.find(tr => tr.getMeta(key))?.getMeta(key)
499
+
500
+ /* ── commit / commitAndRight ── */
501
+ if (
502
+ meta?.action === "commit" ||
503
+ meta?.action === "commitAndRight"
504
+ ) {
505
+ if (!oldPluginState.active) {
506
+ return null
507
+ }
508
+ const query = oldPluginState.query
509
+ const latex = query.startsWith("$") ? query.slice(1) : query
510
+
511
+ if (!latex.trim()) {
512
+ // Empty LaTeX: delete the node (edit) or just cancel (new).
513
+ if (oldPluginState.isEdit) {
514
+ const existingNode = newState.doc.nodeAt(
515
+ oldPluginState.mathNodePos
516
+ )
517
+ const tr = newState.tr.delete(
518
+ oldPluginState.mathNodePos,
519
+ oldPluginState.mathNodePos +
520
+ (existingNode?.nodeSize || 1)
521
+ )
522
+ tr.setSelection(
523
+ TextSelection.create(
524
+ tr.doc,
525
+ oldPluginState.mathNodePos
526
+ )
527
+ )
528
+ return tr.setMeta(key, {action: "deactivate"})
529
+ } else {
530
+ // Insert the literal "$" and move cursor past it.
531
+ const tr = newState.tr.insertText(
532
+ "$",
533
+ oldPluginState.from
534
+ )
535
+ tr.setSelection(
536
+ TextSelection.create(
537
+ tr.doc,
538
+ oldPluginState.from + 1
539
+ )
540
+ )
541
+ return tr.setMeta(key, {action: "deactivate"})
542
+ }
543
+ }
544
+
545
+ const equationNode = newState.schema.nodes.equation.create({
546
+ equation: latex
547
+ })
548
+
549
+ if (oldPluginState.isEdit) {
550
+ const existingNode = newState.doc.nodeAt(
551
+ oldPluginState.mathNodePos
552
+ )
553
+ const tr = newState.tr.replaceWith(
554
+ oldPluginState.mathNodePos,
555
+ oldPluginState.mathNodePos +
556
+ (existingNode?.nodeSize || 1),
557
+ equationNode
558
+ )
559
+ tr.setSelection(
560
+ TextSelection.create(
561
+ tr.doc,
562
+ oldPluginState.mathNodePos + equationNode.nodeSize
563
+ )
564
+ )
565
+ return tr.setMeta(key, {action: "deactivate"})
566
+ } else {
567
+ const tr = newState.tr.insert(
568
+ oldPluginState.from,
569
+ equationNode
570
+ )
571
+ tr.setSelection(
572
+ TextSelection.create(
573
+ tr.doc,
574
+ oldPluginState.from + equationNode.nodeSize
575
+ )
576
+ )
577
+ return tr.setMeta(key, {action: "deactivate"})
578
+ }
579
+ }
580
+
581
+ /* ── cancel ── */
582
+ if (meta?.action === "cancel") {
583
+ if (oldPluginState.isEdit) {
584
+ // Leave the equation node unchanged; move cursor after it.
585
+ const node = newState.doc.nodeAt(oldPluginState.mathNodePos)
586
+ const tr = newState.tr.setSelection(
587
+ TextSelection.create(
588
+ newState.doc,
589
+ oldPluginState.mathNodePos + (node?.nodeSize || 1)
590
+ )
591
+ )
592
+ return tr.setMeta(key, {action: "deactivate"})
593
+ } else {
594
+ // Restore the literal "$" at the original position.
595
+ const tr = newState.tr.insertText("$", oldPluginState.from)
596
+ tr.setSelection(
597
+ TextSelection.create(tr.doc, oldPluginState.from + 1)
598
+ )
599
+ return tr.setMeta(key, {action: "deactivate"})
600
+ }
601
+ }
602
+
603
+ /* ── cancelDelete ── */
604
+ if (meta?.action === "cancelDelete") {
605
+ if (oldPluginState.isEdit) {
606
+ // Delete the equation node entirely.
607
+ const existingNode = newState.doc.nodeAt(
608
+ oldPluginState.mathNodePos
609
+ )
610
+ const tr = newState.tr.delete(
611
+ oldPluginState.mathNodePos,
612
+ oldPluginState.mathNodePos +
613
+ (existingNode?.nodeSize || 1)
614
+ )
615
+ tr.setSelection(
616
+ TextSelection.create(tr.doc, oldPluginState.mathNodePos)
617
+ )
618
+ return tr.setMeta(key, {action: "deactivate"})
619
+ } else {
620
+ // New node: just deactivate — don't insert anything.
621
+ return newState.tr.setMeta(key, {action: "deactivate"})
622
+ }
623
+ }
624
+
625
+ /* ── cancelLeft ── */
626
+ if (meta?.action === "cancelLeft") {
627
+ if (oldPluginState.isEdit) {
628
+ const tr = newState.tr.setSelection(
629
+ TextSelection.create(
630
+ newState.doc,
631
+ oldPluginState.mathNodePos
632
+ )
633
+ )
634
+ return tr.setMeta(key, {action: "deactivate"})
635
+ } else {
636
+ const tr = newState.tr.insertText("$", oldPluginState.from)
637
+ tr.setSelection(
638
+ TextSelection.create(tr.doc, oldPluginState.from)
639
+ )
640
+ return tr.setMeta(key, {action: "deactivate"})
641
+ }
642
+ }
643
+
644
+ /* ── implicit commit when selection moves away ── */
645
+ if (oldPluginState.active) {
646
+ if (
647
+ trs.some(tr => tr.selectionSet) &&
648
+ (newState.selection.from !== oldPluginState.from ||
649
+ newState.selection.to !== oldPluginState.from)
650
+ ) {
651
+ const query = oldPluginState.query
652
+ const latex = query.startsWith("$") ? query.slice(1) : query
653
+
654
+ if (latex.trim()) {
655
+ const equationNode =
656
+ newState.schema.nodes.equation.create({
657
+ equation: latex
658
+ })
659
+ if (oldPluginState.isEdit) {
660
+ const existingNode = newState.doc.nodeAt(
661
+ oldPluginState.mathNodePos
662
+ )
663
+ return newState.tr
664
+ .replaceWith(
665
+ oldPluginState.mathNodePos,
666
+ oldPluginState.mathNodePos +
667
+ (existingNode?.nodeSize || 1),
668
+ equationNode
669
+ )
670
+ .setMeta(key, {action: "deactivate"})
671
+ } else {
672
+ return newState.tr
673
+ .insert(oldPluginState.from, equationNode)
674
+ .setMeta(key, {action: "deactivate"})
675
+ }
676
+ } else {
677
+ return newState.tr.setMeta(key, {action: "deactivate"})
678
+ }
679
+ }
680
+ } else {
681
+ /* ── equation NodeSelection → open inline editor ── */
682
+ const selection = newState.selection
683
+ if (
684
+ selection instanceof NodeSelection &&
685
+ selection.node.type.name === "equation"
686
+ ) {
687
+ const eqNode = selection.node
688
+ const from = selection.from
689
+ return newState.tr.setMeta(key, {
690
+ action: "activate",
691
+ from,
692
+ query: `$${eqNode.attrs.equation}`,
693
+ isEdit: true,
694
+ mathNodePos: from
695
+ })
696
+ }
697
+
698
+ /* ── "$" typed via paste/mobile (doc changed) ── */
699
+ const changedTr = trs.find(tr => tr.docChanged)
700
+ if (changedTr) {
701
+ const $pos = newState.selection.$head
702
+ if (canActivateInlineMath(newState, $pos, editor)) {
703
+ const beforeText = newState.doc.textBetween(
704
+ Math.max(0, $pos.pos - 3),
705
+ $pos.pos,
706
+ ""
707
+ )
708
+ if (beforeText.endsWith("$")) {
709
+ return newState.tr
710
+ .delete($pos.pos - 1, $pos.pos)
711
+ .setMeta(key, {
712
+ action: "activate",
713
+ from: $pos.pos - 1,
714
+ query: "$",
715
+ isEdit: false,
716
+ mathNodePos: 0
717
+ })
718
+ }
719
+ }
720
+ }
721
+ }
722
+
723
+ return null
724
+ },
725
+
726
+ props: {
727
+ decorations(state) {
728
+ const pluginState = key.getState(state)
729
+ return pluginState?.decos || DecorationSet.empty
730
+ },
731
+
732
+ handleClickOn(_view, _pos, node, nodePos, _event, _direct) {
733
+ if (node.type.name === "equation") {
734
+ const tr = _view.state.tr.setSelection(
735
+ TextSelection.create(
736
+ _view.state.doc,
737
+ nodePos + node.nodeSize
738
+ )
739
+ )
740
+ tr.setMeta(key, {
741
+ action: "activate",
742
+ from: nodePos,
743
+ query: `$${node.attrs.equation}`,
744
+ isEdit: true,
745
+ mathNodePos: nodePos
746
+ })
747
+ _view.dispatch(tr)
748
+ return true
749
+ }
750
+ return false
751
+ },
752
+
753
+ handleDOMEvents: {
754
+ mousedown(view, event) {
755
+ if (event.ctrlKey || event.metaKey || event.shiftKey) {
756
+ return false
757
+ }
758
+ if (event.button !== 0) {
759
+ return false
760
+ }
761
+ const target = event.target.closest(".equation")
762
+ if (!target) {
763
+ return false
764
+ }
765
+ let pos = view.posAtDOM(target, 0)
766
+ let node = view.state.doc.nodeAt(pos)
767
+ if (!node || node.type.name !== "equation") {
768
+ return false
769
+ }
770
+
771
+ const pluginState = key.getState(view.state)
772
+ if (pluginState?.active) {
773
+ // Commit the current widget before opening a new one.
774
+ const commitTr = view.state.tr.setMeta(key, {
775
+ action: "commit"
776
+ })
777
+ view.dispatch(commitTr)
778
+ pos = commitTr.mapping.map(pos)
779
+ node = view.state.doc.nodeAt(pos)
780
+ if (!node || node.type.name !== "equation") {
781
+ return false
782
+ }
783
+ }
784
+
785
+ const tr = view.state.tr.setSelection(
786
+ TextSelection.create(
787
+ view.state.doc,
788
+ pos + node.nodeSize
789
+ )
790
+ )
791
+ tr.setMeta(key, {
792
+ action: "activate",
793
+ from: pos,
794
+ query: `$${node.attrs.equation}`,
795
+ isEdit: true,
796
+ mathNodePos: pos
797
+ })
798
+ view.dispatch(tr)
799
+ event.stopPropagation()
800
+ event.preventDefault()
801
+ return true
802
+ },
803
+
804
+ click(view, event) {
805
+ const pluginState = key.getState(view.state)
806
+ if (pluginState?.active) {
807
+ if (event.target.closest(".inline-math-widget")) {
808
+ // Click inside the widget: let the widget handle it.
809
+ return false
810
+ }
811
+ // Widget is active and user clicked elsewhere: the
812
+ // focusout handler will commit asynchronously; prevent
813
+ // the click from doing anything unexpected.
814
+ event.preventDefault()
815
+ event.stopPropagation()
816
+ return true
817
+ }
818
+ return false
819
+ }
820
+ },
821
+
822
+ handleKeyDown(view, event) {
823
+ const pluginState = key.getState(view.state)
824
+ if (!pluginState?.active) {
825
+ /* ── "$" keypress → activate inline editor ── */
826
+ if (event.key === "$") {
827
+ const $pos = view.state.selection.$head
828
+ if (canActivateInlineMath(view.state, $pos, editor)) {
829
+ event.preventDefault()
830
+ view.dispatch(
831
+ view.state.tr.setMeta(key, {
832
+ action: "activate",
833
+ from: $pos.pos,
834
+ query: "$",
835
+ isEdit: false,
836
+ mathNodePos: 0
837
+ })
838
+ )
839
+ return true
840
+ }
841
+ }
842
+
843
+ /* ── ArrowRight into an equation node ── */
844
+ if (event.key === "ArrowRight") {
845
+ const sel = view.state.selection
846
+ if (sel.empty) {
847
+ const nodeAfter = sel.$head.nodeAfter
848
+ if (
849
+ nodeAfter &&
850
+ nodeAfter.type.name === "equation"
851
+ ) {
852
+ event.preventDefault()
853
+ const from = sel.$head.pos
854
+ view.dispatch(
855
+ view.state.tr.setMeta(key, {
856
+ action: "activate",
857
+ from,
858
+ query: `$${nodeAfter.attrs.equation}`,
859
+ isEdit: true,
860
+ mathNodePos: from,
861
+ cursorAtStart: true
862
+ })
863
+ )
864
+ return true
865
+ }
866
+ }
867
+ }
868
+
869
+ /* ── ArrowLeft into an equation node ── */
870
+ if (event.key === "ArrowLeft") {
871
+ const sel = view.state.selection
872
+ if (sel.empty) {
873
+ const nodeBefore = sel.$head.nodeBefore
874
+ if (
875
+ nodeBefore &&
876
+ nodeBefore.type.name === "equation"
877
+ ) {
878
+ event.preventDefault()
879
+ const from = sel.$head.pos - nodeBefore.nodeSize
880
+ view.dispatch(
881
+ view.state.tr.setMeta(key, {
882
+ action: "activate",
883
+ from,
884
+ query: `$${nodeBefore.attrs.equation}`,
885
+ isEdit: true,
886
+ mathNodePos: from,
887
+ cursorAtStart: false
888
+ })
889
+ )
890
+ return true
891
+ }
892
+ }
893
+ }
894
+
895
+ return false
896
+ }
897
+ // When the widget is active it traps its own events; nothing
898
+ // extra needs to be handled here.
899
+ return false
900
+ }
901
+ }
902
+ })
903
+ }
904
+
905
+ /* ────────────────────────────────────────────────────────── */
906
+ /* Public plugin factory */
907
+ /* ────────────────────────────────────────────────────────── */
908
+
909
+ export const inlineMathPlugin = options => {
910
+ const editor = options.editor
911
+
912
+ const enabled =
913
+ editor.app.config.user?.preferences?.inline_math === true &&
914
+ !READ_ONLY_ROLES.includes(editor.docInfo.access_rights) &&
915
+ !COMMENT_ONLY_ROLES.includes(editor.docInfo.access_rights)
916
+
917
+ return enabled ? inlineEditorPlugin(options) : dropupPlugin(options)
918
+ }