@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,1134 @@
1
+ import { NodeSelection, Plugin, PluginKey, TextSelection } from "prosemirror-state";
2
+ import { Decoration, DecorationSet } from "prosemirror-view";
3
+ import { COMMENT_ONLY_ROLES, READ_ONLY_ROLES } from "../..";
4
+ import { elementDisabled } from "../../menus/toolbar/model";
5
+ import { buildBibliographyList, buildCrossRefList, createInlineReferenceDropUp, filterBibliography, filterCrossRefs } from "./dropup";
6
+ const key = new PluginKey("inlineReference");
7
+ export const getInlineReferenceState = state => key.getState(state);
8
+ export const setInlineReferenceState = (tr, state) => tr.setMeta(key, state);
9
+ /**
10
+ * Check if citations can be inserted at the given position.
11
+ * Checks both the ProseMirror schema and document-template restrictions
12
+ * (allowed elements per doc part, protected sections) — the same conditions
13
+ * that disable the toolbar citation button.
14
+ */
15
+ function canActivateInlineReference(editor) {
16
+ // Mirror the template-based restriction check used by the toolbar button.
17
+ if (editor &&
18
+ elementDisabled(editor, "citation") &&
19
+ elementDisabled(editor, "cross_reference")) {
20
+ return false;
21
+ }
22
+ return true;
23
+ }
24
+ /**
25
+ * Parse inline citation text into references array.
26
+ * Format: @key[prefix][locator];key2[prefix2][locator2]
27
+ * Returns {references, format} or null if any key cannot be resolved.
28
+ */
29
+ function parseCitationText(text, bibEntries, bibDB) {
30
+ let format = "autocite";
31
+ let body = text;
32
+ if (body.startsWith("@@")) {
33
+ format = "textcite";
34
+ body = body.slice(2);
35
+ }
36
+ else if (body.startsWith("@")) {
37
+ body = body.slice(1);
38
+ }
39
+ if (!body) {
40
+ return null;
41
+ }
42
+ const references = [];
43
+ const parts = body.split(";");
44
+ for (const part of parts) {
45
+ const match = part.match(/^([^\[]+)(?:\[(.*?)\])?(?:\[(.*?)\])?$/);
46
+ if (!match) {
47
+ return null;
48
+ }
49
+ const entryKey = match[1].trim();
50
+ if (!entryKey) {
51
+ continue;
52
+ }
53
+ const bibEntry = bibEntries.find(entry => entry.entry_key === entryKey);
54
+ if (!bibEntry) {
55
+ return null;
56
+ }
57
+ let id = bibEntry.id;
58
+ if (bibEntry.source === "user") {
59
+ // bibEntry.entry is the raw entry object from the user's bibDB
60
+ // (stored by buildBibliographyList). We must NOT look it up via
61
+ // bibDB.db[id] because bibDB is the *document* bibDB and the user's
62
+ // id doesn't exist there yet — that lookup returns undefined, which
63
+ // addReference then writes into the document DB, corrupting it.
64
+ id = bibDB.addReference(bibEntry.entry, id);
65
+ }
66
+ const ref = { id };
67
+ if (match[2]) {
68
+ ref.prefix = match[2];
69
+ }
70
+ if (match[3]) {
71
+ ref.locator = match[3];
72
+ }
73
+ references.push(ref);
74
+ }
75
+ if (!references.length) {
76
+ return null;
77
+ }
78
+ return { references, format };
79
+ }
80
+ /**
81
+ * Extract the active reference index based on cursor offset.
82
+ */
83
+ function getActiveRefIndex(text, cursorOffset) {
84
+ let pos = 0;
85
+ const parts = text.split(";");
86
+ for (let i = 0; i < parts.length; i++) {
87
+ const partLen = parts[i].length;
88
+ if (cursorOffset <= pos + partLen) {
89
+ return i;
90
+ }
91
+ pos += partLen + 1;
92
+ }
93
+ return Math.max(0, parts.length - 1);
94
+ }
95
+ /**
96
+ * Get the query (key being typed) for the active reference.
97
+ */
98
+ function getActiveQuery(text, activeIndex) {
99
+ const parts = text.split(";");
100
+ let part = parts[activeIndex] || "";
101
+ if (part.startsWith("@@")) {
102
+ part = part.slice(2);
103
+ }
104
+ else if (part.startsWith("@")) {
105
+ part = part.slice(1);
106
+ }
107
+ const match = part.match(/^([^\[]*)/);
108
+ return match ? match[1] : "";
109
+ }
110
+ /**
111
+ * Replace the key of the active reference while preserving prefix/locator.
112
+ */
113
+ function replaceActiveKey(text, activeIndex, newKey) {
114
+ const parts = text.split(";");
115
+ let part = parts[activeIndex] || "";
116
+ let trigger = "";
117
+ if (part.startsWith("@@")) {
118
+ trigger = "@@";
119
+ part = part.slice(2);
120
+ }
121
+ else if (part.startsWith("@")) {
122
+ trigger = "@";
123
+ part = part.slice(1);
124
+ }
125
+ const suffixMatch = part.match(/^[^\[]*(\[.*)$/);
126
+ const suffix = suffixMatch ? suffixMatch[1] : "";
127
+ parts[activeIndex] = trigger + newKey + suffix;
128
+ return parts.join(";");
129
+ }
130
+ /**
131
+ * Convert a citation node back to its inline text representation.
132
+ */
133
+ function citationToText(node, bibEntries) {
134
+ const format = node.attrs.format;
135
+ const references = node.attrs.references || [];
136
+ const parts = references.map(ref => {
137
+ const entry = bibEntries.find(e => e.id === ref.id);
138
+ const key = entry ? entry.entry_key : "";
139
+ let part = key;
140
+ if (ref.prefix) {
141
+ part += `[${ref.prefix}]`;
142
+ }
143
+ if (ref.locator) {
144
+ part += `[${ref.locator}]`;
145
+ }
146
+ return part;
147
+ });
148
+ const body = parts.join(";");
149
+ if (format === "textcite") {
150
+ return "@@" + body;
151
+ }
152
+ return "@" + body;
153
+ }
154
+ function getInputCursorPos(el) {
155
+ const sel = window.getSelection();
156
+ if (!sel || !sel.rangeCount) {
157
+ return (el.textContent || "").length;
158
+ }
159
+ const range = sel.getRangeAt(0);
160
+ if (!el.contains(range.startContainer)) {
161
+ return (el.textContent || "").length;
162
+ }
163
+ return range.startOffset;
164
+ }
165
+ function setInputCursorPos(el, pos) {
166
+ const textNode = el.firstChild;
167
+ if (!textNode) {
168
+ return;
169
+ }
170
+ const range = document.createRange();
171
+ const safePos = Math.max(0, Math.min(pos, textNode.length));
172
+ range.setStart(textNode, safePos);
173
+ range.collapse(true);
174
+ const sel = window.getSelection();
175
+ if (sel) {
176
+ sel.removeAllRanges();
177
+ sel.addRange(range);
178
+ }
179
+ }
180
+ /**
181
+ * Create the inline citation widget DOM element.
182
+ */
183
+ function createInlineReferenceWidget(editor, pluginState, key) {
184
+ const view = editor.currentView || editor.view;
185
+ const container = document.createElement("span");
186
+ container.className = "inline-reference-widget";
187
+ // Build the cross-reference target list once at widget creation time.
188
+ const crossRefList = buildCrossRefList(editor);
189
+ const input = document.createElement("span");
190
+ input.contentEditable = "plaintext-only";
191
+ input.spellcheck = false;
192
+ input.className = "inline-reference-input";
193
+ input.textContent = pluginState.query;
194
+ const dropUpWrapper = document.createElement("span");
195
+ dropUpWrapper.className = "drop-up-outer inline-reference-drop-up";
196
+ function renderDropUp() {
197
+ const currentState = key.getState(view.state);
198
+ if (!currentState?.active) {
199
+ return;
200
+ }
201
+ const rawText = input.textContent || "";
202
+ const citDisabled = elementDisabled(editor, "citation");
203
+ const xrefDisabled = elementDisabled(editor, "cross_reference");
204
+ const isXrefMode = !xrefDisabled && rawText.startsWith("@#");
205
+ let citationMatches, xrefMatches, activeCitIndex;
206
+ if (isXrefMode) {
207
+ // Cross-reference mode: only show cross-refs, filter by id/text
208
+ citationMatches = [];
209
+ xrefMatches = filterCrossRefs(crossRefList, rawText.slice(2));
210
+ activeCitIndex = -1;
211
+ }
212
+ else {
213
+ const cursorPos = getInputCursorPos(input);
214
+ activeCitIndex = getActiveRefIndex(rawText, cursorPos);
215
+ const query = getActiveQuery(rawText, activeCitIndex);
216
+ citationMatches = citDisabled
217
+ ? []
218
+ : filterBibliography(currentState.bibList, query);
219
+ xrefMatches = xrefDisabled
220
+ ? []
221
+ : filterCrossRefs(crossRefList, query);
222
+ }
223
+ const totalMatches = citationMatches.length + xrefMatches.length;
224
+ const selectedIndex = currentState.listActive
225
+ ? Math.max(0, Math.min(currentState.selectedIndex, totalMatches - 1))
226
+ : -1;
227
+ dropUpWrapper.innerHTML = "";
228
+ const dropUp = createInlineReferenceDropUp(citationMatches, selectedIndex, idx => {
229
+ if (idx < citationMatches.length) {
230
+ const entry = citationMatches[idx];
231
+ if (!entry) {
232
+ return;
233
+ }
234
+ const newText = replaceActiveKey(rawText, activeCitIndex, entry.entry_key);
235
+ input.textContent = newText;
236
+ // Move cursor to end of replaced key
237
+ const newCursor = newText.indexOf(entry.entry_key, newText.indexOf("@") + 1);
238
+ setInputCursorPos(input, newCursor + entry.entry_key.length);
239
+ view.dispatch(view.state.tr.setMeta(key, {
240
+ action: "updateQuery",
241
+ query: input.textContent
242
+ }));
243
+ renderDropUp();
244
+ }
245
+ else {
246
+ // Cross-reference selected: fill input with @#id, stay open
247
+ const target = xrefMatches[idx - citationMatches.length];
248
+ if (!target) {
249
+ return;
250
+ }
251
+ input.textContent = `@#${target.id}`;
252
+ setInputCursorPos(input, input.textContent.length);
253
+ view.dispatch(view.state.tr.setMeta(key, {
254
+ action: "updateQuery",
255
+ query: input.textContent
256
+ }));
257
+ renderDropUp();
258
+ }
259
+ }, xrefMatches);
260
+ dropUpWrapper.appendChild(dropUp);
261
+ // Scroll selected item into view
262
+ const selectedItem = dropUp.querySelector(".inline-reference-drop-up-item.fw-selected");
263
+ if (selectedItem) {
264
+ selectedItem.scrollIntoView({ block: "nearest" });
265
+ }
266
+ }
267
+ input.addEventListener("input", event => {
268
+ event.stopPropagation();
269
+ const text = input.textContent || "";
270
+ if (!text) {
271
+ // Everything including `@` was deleted — remove the node.
272
+ view.dispatch(view.state.tr.setMeta(key, { action: "cancelDelete" }));
273
+ view.focus();
274
+ return;
275
+ }
276
+ if (!text.startsWith("@")) {
277
+ // `@` was removed but content remains — restore it.
278
+ const cursorPos = getInputCursorPos(input);
279
+ input.textContent = "@" + text;
280
+ setInputCursorPos(input, cursorPos + 1);
281
+ }
282
+ view.dispatch(view.state.tr.setMeta(key, {
283
+ action: "updateQuery",
284
+ query: input.textContent
285
+ }));
286
+ renderDropUp();
287
+ });
288
+ input.addEventListener("keypress", event => {
289
+ event.stopPropagation();
290
+ });
291
+ input.addEventListener("keydown", event => {
292
+ event.stopPropagation();
293
+ const currentState = key.getState(view.state);
294
+ if (!currentState?.active) {
295
+ return;
296
+ }
297
+ switch (event.key) {
298
+ case "ArrowLeft":
299
+ if (getInputCursorPos(input) === 0) {
300
+ event.preventDefault();
301
+ view.dispatch(view.state.tr.setMeta(key, { action: "cancelLeft" }));
302
+ view.focus();
303
+ }
304
+ break;
305
+ case "ArrowRight":
306
+ if (getInputCursorPos(input) ===
307
+ (input.textContent || "").length) {
308
+ event.preventDefault();
309
+ view.dispatch(view.state.tr.setMeta(key, { action: "commitAndRight" }));
310
+ view.focus();
311
+ }
312
+ break;
313
+ case "ArrowDown":
314
+ event.preventDefault();
315
+ {
316
+ const currentState = key.getState(view.state);
317
+ if (!currentState.listActive) {
318
+ view.dispatch(view.state.tr.setMeta(key, {
319
+ action: "select",
320
+ index: 0,
321
+ listActive: true
322
+ }));
323
+ }
324
+ else {
325
+ view.dispatch(view.state.tr.setMeta(key, {
326
+ action: "select",
327
+ index: currentState.selectedIndex + 1,
328
+ listActive: true
329
+ }));
330
+ }
331
+ renderDropUp();
332
+ }
333
+ break;
334
+ case "ArrowUp":
335
+ event.preventDefault();
336
+ {
337
+ const currentState = key.getState(view.state);
338
+ if (currentState.listActive &&
339
+ currentState.selectedIndex > 0) {
340
+ view.dispatch(view.state.tr.setMeta(key, {
341
+ action: "select",
342
+ index: currentState.selectedIndex - 1,
343
+ listActive: true
344
+ }));
345
+ }
346
+ else {
347
+ view.dispatch(view.state.tr.setMeta(key, {
348
+ action: "select",
349
+ index: -1,
350
+ listActive: false
351
+ }));
352
+ }
353
+ renderDropUp();
354
+ }
355
+ break;
356
+ case "Enter":
357
+ event.preventDefault();
358
+ {
359
+ const currentState = key.getState(view.state);
360
+ const rawText = input.textContent || "";
361
+ const citDisabledEnter = elementDisabled(editor, "citation");
362
+ const xrefDisabledEnter = elementDisabled(editor, "cross_reference");
363
+ const isXrefMode = !xrefDisabledEnter && rawText.startsWith("@#");
364
+ let citMatches, xrefMatchesEnter, activeIndexEnter;
365
+ if (isXrefMode) {
366
+ citMatches = [];
367
+ xrefMatchesEnter = filterCrossRefs(crossRefList, rawText.slice(2));
368
+ activeIndexEnter = -1;
369
+ }
370
+ else {
371
+ const cursorPos = getInputCursorPos(input);
372
+ activeIndexEnter = getActiveRefIndex(rawText, cursorPos);
373
+ const query = getActiveQuery(rawText, activeIndexEnter);
374
+ citMatches = citDisabledEnter
375
+ ? []
376
+ : filterBibliography(currentState.bibList, query);
377
+ xrefMatchesEnter = xrefDisabledEnter
378
+ ? []
379
+ : filterCrossRefs(crossRefList, query);
380
+ }
381
+ const totalEnter = citMatches.length + xrefMatchesEnter.length;
382
+ const selectedIndex = Math.max(0, Math.min(currentState.selectedIndex, totalEnter - 1));
383
+ if (currentState.listActive &&
384
+ totalEnter > 0 &&
385
+ currentState.selectedIndex >= 0) {
386
+ if (selectedIndex < citMatches.length) {
387
+ // Insert selected citation key into input
388
+ const entry = citMatches[selectedIndex];
389
+ const newText = replaceActiveKey(rawText, activeIndexEnter, entry.entry_key);
390
+ input.textContent = newText;
391
+ const newCursor = newText.indexOf(entry.entry_key, newText.indexOf("@") + 1) + entry.entry_key.length;
392
+ setInputCursorPos(input, newCursor);
393
+ view.dispatch(view.state.tr.setMeta(key, {
394
+ action: "updateQuery",
395
+ query: input.textContent
396
+ }));
397
+ renderDropUp();
398
+ }
399
+ else {
400
+ // Cross-reference selected: fill input with @#id, stay open
401
+ const target = xrefMatchesEnter[selectedIndex - citMatches.length];
402
+ input.textContent = `@#${target.id}`;
403
+ setInputCursorPos(input, input.textContent.length);
404
+ view.dispatch(view.state.tr.setMeta(key, {
405
+ action: "updateQuery",
406
+ query: input.textContent
407
+ }));
408
+ renderDropUp();
409
+ }
410
+ }
411
+ else {
412
+ // Not in list mode or no matches: commit what we have
413
+ view.dispatch(view.state.tr.setMeta(key, { action: "commit" }));
414
+ view.focus();
415
+ }
416
+ }
417
+ break;
418
+ case "Escape":
419
+ event.preventDefault();
420
+ view.dispatch(view.state.tr.setMeta(key, { action: "cancel" }));
421
+ view.focus();
422
+ break;
423
+ case "Home":
424
+ event.preventDefault();
425
+ setInputCursorPos(input, 0);
426
+ break;
427
+ case "End":
428
+ event.preventDefault();
429
+ setInputCursorPos(input, (input.textContent || "").length);
430
+ break;
431
+ case "Backspace":
432
+ // When only `@` remains, delete the whole node.
433
+ if ((input.textContent || "").length <= 1) {
434
+ event.preventDefault();
435
+ view.dispatch(view.state.tr.setMeta(key, { action: "cancelDelete" }));
436
+ view.focus();
437
+ }
438
+ break;
439
+ case "Delete":
440
+ // Same as Backspace when only `@` is left.
441
+ if ((input.textContent || "").length <= 1) {
442
+ event.preventDefault();
443
+ view.dispatch(view.state.tr.setMeta(key, { action: "cancelDelete" }));
444
+ view.focus();
445
+ }
446
+ break;
447
+ case "Tab":
448
+ event.preventDefault();
449
+ view.dispatch(view.state.tr.setMeta(key, { action: "commit" }));
450
+ break;
451
+ default:
452
+ break;
453
+ }
454
+ });
455
+ input.addEventListener("focusout", event => {
456
+ const related = event.relatedTarget;
457
+ if (container.contains(related)) {
458
+ return;
459
+ }
460
+ const myWidgetId = pluginState.widgetId;
461
+ setTimeout(() => {
462
+ const currentState = key.getState(view.state);
463
+ if (currentState?.active && currentState.widgetId === myWidgetId) {
464
+ view.dispatch(view.state.tr.setMeta(key, { action: "commit" }));
465
+ }
466
+ }, 1);
467
+ });
468
+ container.addEventListener("mousedown", event => {
469
+ event.stopPropagation();
470
+ });
471
+ container.appendChild(input);
472
+ container.appendChild(dropUpWrapper);
473
+ // Focus after mounting
474
+ setTimeout(() => {
475
+ input.focus();
476
+ // Place cursor based on entry direction
477
+ if (pluginState.cursorAtStart === true) {
478
+ setInputCursorPos(input, 0);
479
+ }
480
+ else {
481
+ setInputCursorPos(input, (input.textContent || "").length);
482
+ }
483
+ renderDropUp();
484
+ }, 0);
485
+ return container;
486
+ }
487
+ export const inlineReferencePlugin = options => {
488
+ const editor = options.editor;
489
+ const bibDB = editor.mod.db.bibDB;
490
+ const enabled = editor.app.config.user?.preferences?.inline_references === true &&
491
+ !READ_ONLY_ROLES.includes(editor.docInfo.access_rights) &&
492
+ !COMMENT_ONLY_ROLES.includes(editor.docInfo.access_rights);
493
+ if (!enabled) {
494
+ return new Plugin({
495
+ key,
496
+ state: {
497
+ init() {
498
+ return { active: false };
499
+ },
500
+ apply() {
501
+ return { active: false };
502
+ }
503
+ }
504
+ });
505
+ }
506
+ return new Plugin({
507
+ key,
508
+ state: {
509
+ init() {
510
+ return {
511
+ active: false,
512
+ from: 0,
513
+ query: "",
514
+ selectedIndex: -1,
515
+ listActive: false,
516
+ isEdit: false,
517
+ referenceNodePos: 0,
518
+ bibList: [],
519
+ widgetId: undefined,
520
+ cursorAtStart: undefined,
521
+ decos: DecorationSet.empty
522
+ };
523
+ },
524
+ apply(tr, prev, _oldState, _state) {
525
+ let next = { ...prev };
526
+ const meta = tr.getMeta(key);
527
+ if (meta?.action === "activate") {
528
+ next = {
529
+ active: true,
530
+ from: meta.from,
531
+ query: meta.query || "",
532
+ selectedIndex: -1,
533
+ listActive: false,
534
+ isEdit: meta.isEdit || false,
535
+ referenceNodePos: meta.referenceNodePos || 0,
536
+ bibList: meta.bibList || [],
537
+ widgetId: Math.random().toString(36).slice(2),
538
+ cursorAtStart: meta.cursorAtStart,
539
+ decos: DecorationSet.empty
540
+ };
541
+ }
542
+ else if (meta?.action === "deactivate") {
543
+ next = {
544
+ active: false,
545
+ from: 0,
546
+ query: "",
547
+ selectedIndex: -1,
548
+ listActive: false,
549
+ isEdit: false,
550
+ referenceNodePos: 0,
551
+ bibList: [],
552
+ widgetId: undefined,
553
+ cursorAtStart: undefined,
554
+ decos: DecorationSet.empty
555
+ };
556
+ }
557
+ else if (meta?.action === "select") {
558
+ next.selectedIndex = meta.index;
559
+ if (meta.listActive !== undefined) {
560
+ next.listActive = meta.listActive;
561
+ }
562
+ }
563
+ else if (meta?.action === "updateQuery") {
564
+ next.query = meta.query;
565
+ next.selectedIndex = -1;
566
+ next.listActive = false;
567
+ }
568
+ if (next.active) {
569
+ if (!prev.active || prev.from !== next.from) {
570
+ // Position changed or just activated: create new widget
571
+ const deco = Decoration.widget(next.from, () => {
572
+ return createInlineReferenceWidget(editor, next, key);
573
+ }, {
574
+ key: "inline-reference-widget",
575
+ side: -1
576
+ });
577
+ const referenceNodeDeco = Decoration.node(next.from, next.from + 1, {
578
+ class: "hide"
579
+ });
580
+ next.decos = DecorationSet.create(_state.doc, [
581
+ deco,
582
+ referenceNodeDeco
583
+ ]);
584
+ }
585
+ else if (tr.docChanged) {
586
+ // Document changed while active: map old decorations
587
+ next.decos = prev.decos.map(tr.mapping, _state.doc);
588
+ }
589
+ else {
590
+ // Same position, doc unchanged: keep existing widget
591
+ next.decos = prev.decos;
592
+ }
593
+ }
594
+ else {
595
+ next.decos = DecorationSet.empty;
596
+ }
597
+ return next;
598
+ }
599
+ },
600
+ appendTransaction: (trs, oldState, newState) => {
601
+ const oldPluginState = key.getState(oldState);
602
+ const meta = trs.find(tr => tr.getMeta(key))?.getMeta(key);
603
+ if (meta?.action === "commit" ||
604
+ meta?.action === "commitAndRight") {
605
+ if (!oldPluginState.active) {
606
+ return null;
607
+ }
608
+ const query = oldPluginState.query;
609
+ // Cross-reference mode: query starts with '@#'
610
+ if (query.startsWith("@#") &&
611
+ !elementDisabled(editor, "cross_reference")) {
612
+ const xrefId = query.slice(2);
613
+ const crossRefList = buildCrossRefList(editor);
614
+ const target = crossRefList.find(t => t.id === xrefId);
615
+ const crossRefNode = newState.schema.nodes.cross_reference.create({
616
+ id: xrefId || false,
617
+ title: target ? target.text : null
618
+ });
619
+ if (oldPluginState.isEdit) {
620
+ const existingNode = newState.doc.nodeAt(oldPluginState.referenceNodePos);
621
+ const tr = newState.tr.replaceWith(oldPluginState.referenceNodePos, oldPluginState.referenceNodePos +
622
+ (existingNode?.nodeSize || 1), crossRefNode);
623
+ tr.setSelection(TextSelection.create(tr.doc, oldPluginState.referenceNodePos +
624
+ crossRefNode.nodeSize));
625
+ return tr.setMeta(key, { action: "deactivate" });
626
+ }
627
+ else {
628
+ const tr = newState.tr.insert(oldPluginState.from, crossRefNode);
629
+ const newPos = oldPluginState.from + crossRefNode.nodeSize;
630
+ tr.setSelection(TextSelection.create(tr.doc, newPos));
631
+ return tr.setMeta(key, { action: "deactivate" });
632
+ }
633
+ }
634
+ const parsed = !elementDisabled(editor, "citation")
635
+ ? parseCitationText(query, oldPluginState.bibList, bibDB)
636
+ : null;
637
+ if (!parsed) {
638
+ if (oldPluginState.isEdit) {
639
+ const node = newState.doc.nodeAt(oldPluginState.referenceNodePos);
640
+ const newPos = oldPluginState.referenceNodePos +
641
+ (node?.nodeSize || 1);
642
+ const tr = newState.tr.setSelection(TextSelection.create(newState.doc, newPos));
643
+ return tr.setMeta(key, { action: "deactivate" });
644
+ }
645
+ // Invalid reference text: insert as plain text with caret after
646
+ const tr = newState.tr.insertText(query, oldPluginState.from);
647
+ const newPos = oldPluginState.from + query.length;
648
+ tr.setSelection(TextSelection.create(tr.doc, newPos));
649
+ return tr.setMeta(key, { action: "deactivate" });
650
+ }
651
+ const citationNode = newState.schema.nodes.citation.create({
652
+ format: parsed.format,
653
+ references: parsed.references
654
+ });
655
+ if (oldPluginState.isEdit) {
656
+ const existingNode = newState.doc.nodeAt(oldPluginState.referenceNodePos);
657
+ const tr = newState.tr.replaceWith(oldPluginState.referenceNodePos, oldPluginState.referenceNodePos +
658
+ (existingNode?.nodeSize || 1), citationNode);
659
+ const newPos = oldPluginState.referenceNodePos + citationNode.nodeSize;
660
+ tr.setSelection(TextSelection.create(tr.doc, newPos));
661
+ return tr.setMeta(key, { action: "deactivate" });
662
+ }
663
+ else {
664
+ const tr = newState.tr.insert(oldPluginState.from, citationNode);
665
+ const newPos = oldPluginState.from + citationNode.nodeSize;
666
+ tr.setSelection(TextSelection.create(tr.doc, newPos));
667
+ return tr.setMeta(key, { action: "deactivate" });
668
+ }
669
+ }
670
+ if (meta?.action === "cancel") {
671
+ if (oldPluginState.isEdit) {
672
+ // Editing: just deactivate, leave reference unchanged
673
+ const node = newState.doc.nodeAt(oldPluginState.referenceNodePos);
674
+ const newPos = oldPluginState.referenceNodePos + (node?.nodeSize || 1);
675
+ const tr = newState.tr.setSelection(TextSelection.create(newState.doc, newPos));
676
+ return tr.setMeta(key, { action: "deactivate" });
677
+ }
678
+ else {
679
+ // New reference: insert query as plain text with caret after
680
+ const tr = newState.tr.insertText(oldPluginState.query, oldPluginState.from);
681
+ const newPos = oldPluginState.from + oldPluginState.query.length;
682
+ tr.setSelection(TextSelection.create(tr.doc, newPos));
683
+ return tr.setMeta(key, { action: "deactivate" });
684
+ }
685
+ }
686
+ if (meta?.action === "cancelDelete") {
687
+ if (oldPluginState.isEdit) {
688
+ // Delete the reference node entirely.
689
+ const existingNode = newState.doc.nodeAt(oldPluginState.referenceNodePos);
690
+ const tr = newState.tr.delete(oldPluginState.referenceNodePos, oldPluginState.referenceNodePos +
691
+ (existingNode?.nodeSize || 1));
692
+ tr.setSelection(TextSelection.create(tr.doc, oldPluginState.referenceNodePos));
693
+ return tr.setMeta(key, { action: "deactivate" });
694
+ }
695
+ else {
696
+ // New node: just deactivate — don't insert anything.
697
+ return newState.tr.setMeta(key, { action: "deactivate" });
698
+ }
699
+ }
700
+ if (meta?.action === "cancelLeft") {
701
+ if (oldPluginState.isEdit) {
702
+ const tr = newState.tr.setSelection(TextSelection.create(newState.doc, oldPluginState.referenceNodePos));
703
+ return tr.setMeta(key, { action: "deactivate" });
704
+ }
705
+ else {
706
+ const tr = newState.tr.insertText(oldPluginState.query, oldPluginState.from);
707
+ tr.setSelection(TextSelection.create(tr.doc, oldPluginState.from));
708
+ return tr.setMeta(key, { action: "deactivate" });
709
+ }
710
+ }
711
+ if (meta?.action === "openDialog") {
712
+ if (oldPluginState.active && oldPluginState.isEdit) {
713
+ // Deactivate the inline editor and leave a NodeSelection on
714
+ // the citation so CitationDialog opens with its content.
715
+ const node = newState.doc.nodeAt(oldPluginState.referenceNodePos);
716
+ if (node?.type.name === "citation") {
717
+ return newState.tr
718
+ .setSelection(NodeSelection.create(newState.doc, oldPluginState.referenceNodePos))
719
+ .setMeta(key, { action: "deactivate" });
720
+ }
721
+ }
722
+ return null;
723
+ }
724
+ if (meta?.action === "insertCrossRef") {
725
+ if (!oldPluginState.active) {
726
+ return null;
727
+ }
728
+ const crossRefNode = newState.schema.nodes.cross_reference.create({
729
+ id: meta.id,
730
+ title: meta.title
731
+ });
732
+ if (oldPluginState.isEdit) {
733
+ // Replace the existing citation node with a cross_reference.
734
+ const existingNode = newState.doc.nodeAt(oldPluginState.referenceNodePos);
735
+ const tr = newState.tr.replaceWith(oldPluginState.referenceNodePos, oldPluginState.referenceNodePos +
736
+ (existingNode?.nodeSize || 1), crossRefNode);
737
+ tr.setSelection(TextSelection.create(tr.doc, oldPluginState.referenceNodePos +
738
+ crossRefNode.nodeSize));
739
+ return tr.setMeta(key, { action: "deactivate" });
740
+ }
741
+ else {
742
+ const tr = newState.tr.insert(oldPluginState.from, crossRefNode);
743
+ tr.setSelection(TextSelection.create(tr.doc, oldPluginState.from + crossRefNode.nodeSize));
744
+ return tr.setMeta(key, { action: "deactivate" });
745
+ }
746
+ }
747
+ if (oldPluginState.active) {
748
+ // If selection moved away from the widget, commit
749
+ if (trs.some(tr => tr.selectionSet) &&
750
+ (newState.selection.from !== oldPluginState.from ||
751
+ newState.selection.to !== oldPluginState.from)) {
752
+ const query = oldPluginState.query;
753
+ // Cross-reference mode
754
+ if (query.startsWith("@#") &&
755
+ !elementDisabled(editor, "cross_reference")) {
756
+ const xrefId = query.slice(2);
757
+ if (xrefId && oldPluginState.isEdit) {
758
+ const crossRefList = buildCrossRefList(editor);
759
+ const target = crossRefList.find(t => t.id === xrefId);
760
+ const crossRefNode = newState.schema.nodes.cross_reference.create({
761
+ id: xrefId,
762
+ title: target ? target.text : null
763
+ });
764
+ const existingNode = newState.doc.nodeAt(oldPluginState.referenceNodePos);
765
+ return newState.tr
766
+ .replaceWith(oldPluginState.referenceNodePos, oldPluginState.referenceNodePos +
767
+ (existingNode?.nodeSize || 1), crossRefNode)
768
+ .setMeta(key, { action: "deactivate" });
769
+ }
770
+ else if (xrefId && !oldPluginState.isEdit) {
771
+ const crossRefList = buildCrossRefList(editor);
772
+ const target = crossRefList.find(t => t.id === xrefId);
773
+ const crossRefNode = newState.schema.nodes.cross_reference.create({
774
+ id: xrefId,
775
+ title: target ? target.text : null
776
+ });
777
+ return newState.tr
778
+ .insert(oldPluginState.from, crossRefNode)
779
+ .setMeta(key, { action: "deactivate" });
780
+ }
781
+ else {
782
+ return newState.tr.setMeta(key, {
783
+ action: "deactivate"
784
+ });
785
+ }
786
+ }
787
+ const parsed = !elementDisabled(editor, "citation")
788
+ ? parseCitationText(query, oldPluginState.bibList, bibDB)
789
+ : null;
790
+ if (parsed) {
791
+ const citationNode = newState.schema.nodes.citation.create({
792
+ format: parsed.format,
793
+ references: parsed.references
794
+ });
795
+ if (oldPluginState.isEdit) {
796
+ const existingNode = newState.doc.nodeAt(oldPluginState.referenceNodePos);
797
+ return newState.tr
798
+ .replaceWith(oldPluginState.referenceNodePos, oldPluginState.referenceNodePos +
799
+ (existingNode?.nodeSize || 1), citationNode)
800
+ .setMeta(key, { action: "deactivate" });
801
+ }
802
+ else {
803
+ return newState.tr
804
+ .insert(oldPluginState.from, citationNode)
805
+ .setMeta(key, { action: "deactivate" });
806
+ }
807
+ }
808
+ else if (!oldPluginState.isEdit) {
809
+ // Invalid reference text on blur/selection-move: insert as plain text
810
+ const tr = newState.tr.insertText(query, oldPluginState.from);
811
+ const newPos = oldPluginState.from + query.length;
812
+ tr.setSelection(TextSelection.create(tr.doc, newPos));
813
+ return tr.setMeta(key, { action: "deactivate" });
814
+ }
815
+ else {
816
+ return newState.tr.setMeta(key, {
817
+ action: "deactivate"
818
+ });
819
+ }
820
+ }
821
+ }
822
+ else {
823
+ // Check if a citation node is selected for re-editing (keyboard)
824
+ const selection = newState.selection;
825
+ if (selection instanceof NodeSelection &&
826
+ selection.node.type.name === "citation") {
827
+ const citationNode = selection.node;
828
+ const from = selection.from;
829
+ const bibList = buildBibliographyList(editor);
830
+ const text = citationToText(citationNode, bibList);
831
+ return newState.tr.setMeta(key, {
832
+ action: "activate",
833
+ from: from,
834
+ query: text,
835
+ isEdit: true,
836
+ referenceNodePos: from,
837
+ bibList: bibList
838
+ });
839
+ }
840
+ // Check if a cross_reference node is selected for re-editing (keyboard)
841
+ if (selection instanceof NodeSelection &&
842
+ selection.node.type.name === "cross_reference") {
843
+ const crossNode = selection.node;
844
+ const from = selection.from;
845
+ return newState.tr.setMeta(key, {
846
+ action: "activate",
847
+ from: from,
848
+ query: `@#${crossNode.attrs.id || ""}`,
849
+ isEdit: true,
850
+ referenceNodePos: from,
851
+ bibList: buildBibliographyList(editor)
852
+ });
853
+ }
854
+ // Check for @ keypress activation via doc change
855
+ // (handles paste/mobile where handleKeyDown may not fire)
856
+ const tr = trs.find(tr => tr.docChanged);
857
+ if (tr) {
858
+ const $pos = newState.selection.$head;
859
+ if (canActivateInlineReference(editor)) {
860
+ const beforeText = newState.doc.textBetween(Math.max(0, $pos.pos - 3), $pos.pos, "");
861
+ if (beforeText.endsWith("@")) {
862
+ const lastChar = beforeText.slice(-2, -1);
863
+ if (!lastChar || !/[a-zA-Z0-9]/.test(lastChar)) {
864
+ const tr = newState.tr
865
+ .delete($pos.pos - 1, $pos.pos)
866
+ .setMeta(key, {
867
+ action: "activate",
868
+ from: $pos.pos - 1,
869
+ query: "@",
870
+ isEdit: false,
871
+ bibList: buildBibliographyList(editor)
872
+ });
873
+ return tr;
874
+ }
875
+ }
876
+ }
877
+ }
878
+ }
879
+ return null;
880
+ },
881
+ props: {
882
+ decorations(state) {
883
+ const pluginState = key.getState(state);
884
+ return pluginState?.decos || DecorationSet.empty;
885
+ },
886
+ handleClickOn(_view, _pos, node, nodePos, _event, _direct) {
887
+ if (node.type.name === "citation") {
888
+ const bibList = buildBibliographyList(editor);
889
+ const text = citationToText(node, bibList);
890
+ const tr = _view.state.tr.setSelection(TextSelection.create(_view.state.doc, nodePos + node.nodeSize));
891
+ tr.setMeta(key, {
892
+ action: "activate",
893
+ from: nodePos,
894
+ query: text,
895
+ isEdit: true,
896
+ referenceNodePos: nodePos,
897
+ bibList: bibList
898
+ });
899
+ _view.dispatch(tr);
900
+ return true;
901
+ }
902
+ if (node.type.name === "cross_reference") {
903
+ const tr = _view.state.tr.setSelection(TextSelection.create(_view.state.doc, nodePos + node.nodeSize));
904
+ tr.setMeta(key, {
905
+ action: "activate",
906
+ from: nodePos,
907
+ query: `@#${node.attrs.id || ""}`,
908
+ isEdit: true,
909
+ referenceNodePos: nodePos,
910
+ bibList: buildBibliographyList(editor)
911
+ });
912
+ _view.dispatch(tr);
913
+ return true;
914
+ }
915
+ return false;
916
+ },
917
+ handleDOMEvents: {
918
+ mousedown(view, event) {
919
+ if (event.ctrlKey || event.metaKey || event.shiftKey) {
920
+ return false;
921
+ }
922
+ if (event.button !== 0) {
923
+ return false;
924
+ }
925
+ const citTarget = event.target.closest(".citation");
926
+ const xrefTarget = !citTarget && event.target.closest(".cross-reference");
927
+ const target = citTarget || xrefTarget;
928
+ if (!target) {
929
+ return false;
930
+ }
931
+ let pos = view.posAtDOM(target, 0);
932
+ let node = view.state.doc.nodeAt(pos);
933
+ if (!node ||
934
+ (node.type.name !== "citation" &&
935
+ node.type.name !== "cross_reference")) {
936
+ return false;
937
+ }
938
+ const pluginState = key.getState(view.state);
939
+ if (pluginState?.active) {
940
+ // Commit current widget first
941
+ const commitTr = view.state.tr.setMeta(key, {
942
+ action: "commit"
943
+ });
944
+ view.dispatch(commitTr);
945
+ pos = commitTr.mapping.map(pos);
946
+ node = view.state.doc.nodeAt(pos);
947
+ if (!node ||
948
+ (node.type.name !== "citation" &&
949
+ node.type.name !== "cross_reference")) {
950
+ return false;
951
+ }
952
+ }
953
+ let query, bibList;
954
+ if (node.type.name === "citation") {
955
+ bibList = buildBibliographyList(editor);
956
+ query = citationToText(node, bibList);
957
+ }
958
+ else {
959
+ bibList = buildBibliographyList(editor);
960
+ query = `@#${node.attrs.id || ""}`;
961
+ }
962
+ const tr = view.state.tr.setSelection(TextSelection.create(view.state.doc, pos + node.nodeSize));
963
+ tr.setMeta(key, {
964
+ action: "activate",
965
+ from: pos,
966
+ query,
967
+ isEdit: true,
968
+ referenceNodePos: pos,
969
+ bibList
970
+ });
971
+ view.dispatch(tr);
972
+ event.stopPropagation();
973
+ event.preventDefault();
974
+ return true;
975
+ },
976
+ click(view, event) {
977
+ // Fallback click handler for touch devices and cases where
978
+ // mousedown/handleClickOn did not fire.
979
+ const pluginState = key.getState(view.state);
980
+ if (pluginState?.active) {
981
+ const target = event.target.closest(".inline-reference-widget");
982
+ if (target) {
983
+ // Click inside widget: let widget handle it
984
+ return false;
985
+ }
986
+ // When widget is active, ignore all other clicks.
987
+ // mousedown already handled citation clicks.
988
+ // focusout handles clicks outside the editor.
989
+ // We must prevent default because the browser may
990
+ // retarget click to a parent element after mousedown
991
+ // prevented the default.
992
+ event.preventDefault();
993
+ event.stopPropagation();
994
+ return true;
995
+ }
996
+ // Widget inactive: try to activate a clicked citation
997
+ if (event.ctrlKey || event.metaKey || event.shiftKey) {
998
+ return false;
999
+ }
1000
+ const target = event.target.closest(".citation");
1001
+ if (!target) {
1002
+ return false;
1003
+ }
1004
+ const pos = view.posAtDOM(target, 0);
1005
+ const node = view.state.doc.nodeAt(pos);
1006
+ if (!node || node.type.name !== "citation") {
1007
+ return false;
1008
+ }
1009
+ const bibList = buildBibliographyList(editor);
1010
+ const text = citationToText(node, bibList);
1011
+ const tr = view.state.tr.setSelection(TextSelection.create(view.state.doc, pos + node.nodeSize));
1012
+ tr.setMeta(key, {
1013
+ action: "activate",
1014
+ from: pos,
1015
+ query: text,
1016
+ isEdit: true,
1017
+ referenceNodePos: pos,
1018
+ bibList: bibList
1019
+ });
1020
+ view.dispatch(tr);
1021
+ return true;
1022
+ }
1023
+ },
1024
+ handleKeyDown(view, event) {
1025
+ const pluginState = key.getState(view.state);
1026
+ if (!pluginState?.active) {
1027
+ if (event.key === "@") {
1028
+ const $pos = view.state.selection.$head;
1029
+ if (canActivateInlineReference(editor)) {
1030
+ const beforeText = view.state.doc.textBetween(Math.max(0, $pos.pos - 1), $pos.pos, "");
1031
+ const lastChar = beforeText.slice(-1);
1032
+ if (!lastChar || !/[a-zA-Z0-9]/.test(lastChar)) {
1033
+ event.preventDefault();
1034
+ view.dispatch(view.state.tr.setMeta(key, {
1035
+ action: "activate",
1036
+ from: $pos.pos,
1037
+ query: "@",
1038
+ isEdit: false,
1039
+ bibList: buildBibliographyList(editor)
1040
+ }));
1041
+ return true;
1042
+ }
1043
+ }
1044
+ }
1045
+ // ArrowRight into citation or cross_reference from the left
1046
+ if (event.key === "ArrowRight") {
1047
+ const sel = view.state.selection;
1048
+ if (sel.empty) {
1049
+ const $pos = sel.$head;
1050
+ const nodeAfter = $pos.nodeAfter;
1051
+ if (nodeAfter &&
1052
+ nodeAfter.type.name === "citation") {
1053
+ event.preventDefault();
1054
+ const from = $pos.pos;
1055
+ const bibList = buildBibliographyList(editor);
1056
+ const text = citationToText(nodeAfter, bibList);
1057
+ view.dispatch(view.state.tr.setMeta(key, {
1058
+ action: "activate",
1059
+ from: from,
1060
+ query: text,
1061
+ isEdit: true,
1062
+ referenceNodePos: from,
1063
+ bibList: bibList,
1064
+ cursorAtStart: true
1065
+ }));
1066
+ return true;
1067
+ }
1068
+ if (nodeAfter &&
1069
+ nodeAfter.type.name === "cross_reference") {
1070
+ event.preventDefault();
1071
+ const from = $pos.pos;
1072
+ view.dispatch(view.state.tr.setMeta(key, {
1073
+ action: "activate",
1074
+ from: from,
1075
+ query: `@#${nodeAfter.attrs.id || ""}`,
1076
+ isEdit: true,
1077
+ referenceNodePos: from,
1078
+ bibList: buildBibliographyList(editor),
1079
+ cursorAtStart: true
1080
+ }));
1081
+ return true;
1082
+ }
1083
+ }
1084
+ }
1085
+ // ArrowLeft into citation or cross_reference from the right
1086
+ if (event.key === "ArrowLeft") {
1087
+ const sel = view.state.selection;
1088
+ if (sel.empty) {
1089
+ const $pos = sel.$head;
1090
+ const nodeBefore = $pos.nodeBefore;
1091
+ if (nodeBefore &&
1092
+ nodeBefore.type.name === "citation") {
1093
+ event.preventDefault();
1094
+ const from = $pos.pos - nodeBefore.nodeSize;
1095
+ const bibList = buildBibliographyList(editor);
1096
+ const text = citationToText(nodeBefore, bibList);
1097
+ view.dispatch(view.state.tr.setMeta(key, {
1098
+ action: "activate",
1099
+ from: from,
1100
+ query: text,
1101
+ isEdit: true,
1102
+ referenceNodePos: from,
1103
+ bibList: bibList,
1104
+ cursorAtStart: false
1105
+ }));
1106
+ return true;
1107
+ }
1108
+ if (nodeBefore &&
1109
+ nodeBefore.type.name === "cross_reference") {
1110
+ event.preventDefault();
1111
+ const from = $pos.pos - nodeBefore.nodeSize;
1112
+ view.dispatch(view.state.tr.setMeta(key, {
1113
+ action: "activate",
1114
+ from: from,
1115
+ query: `@#${nodeBefore.attrs.id || ""}`,
1116
+ isEdit: true,
1117
+ referenceNodePos: from,
1118
+ bibList: buildBibliographyList(editor),
1119
+ cursorAtStart: false
1120
+ }));
1121
+ return true;
1122
+ }
1123
+ }
1124
+ }
1125
+ return false;
1126
+ }
1127
+ // When active, the widget traps its own key events.
1128
+ // Only handle navigation keys that should move the main cursor.
1129
+ return false;
1130
+ }
1131
+ }
1132
+ });
1133
+ };
1134
+ //# sourceMappingURL=plugin.js.map