@manuscripts/body-editor 3.12.67 → 3.13.1

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 (289) hide show
  1. package/dist/cjs/components/toolbar/type-selector/styles.js +2 -1
  2. package/dist/cjs/versions.js +1 -1
  3. package/dist/es/components/toolbar/type-selector/styles.js +2 -1
  4. package/dist/es/versions.js +1 -1
  5. package/dist/types/components/toolbar/type-selector/styles.d.ts +2 -2
  6. package/dist/types/lib/footnotes.d.ts +4 -2
  7. package/dist/types/lib/utils.d.ts +5 -4
  8. package/dist/types/versions.d.ts +1 -1
  9. package/package.json +37 -36
  10. package/{dist/es/lib/statistics.js → src/__mocks__/styleMock.ts} +2 -14
  11. package/src/assets.ts +20 -0
  12. package/src/classes/collabProvider.ts +38 -0
  13. package/src/clipboard.ts +54 -0
  14. package/src/commands.ts +2109 -0
  15. package/src/components/ChangeHandlingForm.tsx +54 -0
  16. package/src/components/LanguageDropdown/index.tsx +343 -0
  17. package/src/components/affiliations/AffiliationForm.tsx +238 -0
  18. package/src/components/affiliations/AffiliationItem.tsx +151 -0
  19. package/src/components/affiliations/AffiliationList.tsx +71 -0
  20. package/src/components/affiliations/AffiliationsModal.tsx +676 -0
  21. package/src/components/affiliations/AffiliationsPanel.tsx +76 -0
  22. package/src/components/affiliations/CreateAffiliationModal.tsx +135 -0
  23. package/src/components/authors/AuthorDetailsForm.tsx +438 -0
  24. package/src/components/authors/AuthorList.tsx +81 -0
  25. package/src/components/authors/AuthorsModal.tsx +642 -0
  26. package/src/components/authors/AuthorsPanel.tsx +69 -0
  27. package/src/components/authors/CreateAuthorModal.tsx +172 -0
  28. package/src/components/authors/CreditDrawer.tsx +71 -0
  29. package/src/components/authors/DraggableAuthor.tsx +228 -0
  30. package/src/components/authors/useManageAffiliations.tsx +77 -0
  31. package/src/components/authors/useManageCredit.tsx +63 -0
  32. package/src/components/authors-affiliations/AuthorsAndAffiliationsModals.tsx +170 -0
  33. package/src/components/authors-affiliations/GenericPanel.tsx +164 -0
  34. package/src/components/authors-affiliations/ModalTabs.tsx +100 -0
  35. package/src/components/awards/AwardForm.tsx +338 -0
  36. package/src/components/awards/AwardModal.tsx +120 -0
  37. package/src/components/awards/DeleteAwardDiaolog.tsx +52 -0
  38. package/src/components/dialog/ConfirmationDialog.tsx +131 -0
  39. package/src/components/form/CreateModalStyles.tsx +37 -0
  40. package/src/components/form/FormFooter.tsx +54 -0
  41. package/src/components/form/FormPlaceholder.tsx +71 -0
  42. package/src/components/form/ModalFormActions.tsx +88 -0
  43. package/src/components/form/UnsavedLabel.tsx +49 -0
  44. package/src/components/hooks/use-debounce.ts +56 -0
  45. package/src/components/hooks/useAffiliationShowsErrorIndicator.ts +51 -0
  46. package/src/components/hooks/useAuthorShowsErrorIndicator.ts +73 -0
  47. package/src/components/keyboard-shortcuts-modal/FormattedShortcut.tsx +56 -0
  48. package/src/components/keyboard-shortcuts-modal/KeyboardShortcutsModal.tsx +283 -0
  49. package/src/components/keyboard-shortcuts-modal/keyboard-shortcuts.ts +304 -0
  50. package/src/components/keywords/AddKeywordInline.tsx +284 -0
  51. package/src/components/keywords/DeleteKeywordDialog.tsx +52 -0
  52. package/src/components/modal-drawer/GenericDrawer.tsx +65 -0
  53. package/src/components/modal-drawer/GenericDrawerGroup.tsx +125 -0
  54. package/src/components/outline/DraggableTree.tsx +438 -0
  55. package/src/components/outline/ManuscriptOutline.tsx +127 -0
  56. package/src/components/outline/Outline.tsx +141 -0
  57. package/src/components/references/BibliographyItemSource.ts +80 -0
  58. package/src/components/references/CitationEditor.tsx +301 -0
  59. package/src/components/references/CitationViewer.tsx +62 -0
  60. package/src/components/references/ImportBibliographyForm.tsx +232 -0
  61. package/src/components/references/ImportBibliographyModal.tsx +159 -0
  62. package/src/components/references/ReferenceForm/PersonDropDown.tsx +93 -0
  63. package/src/components/references/ReferenceForm/ReferenceForm.tsx +701 -0
  64. package/src/components/references/ReferenceForm/config.ts +133 -0
  65. package/src/components/references/ReferenceForm/styled-components.ts +156 -0
  66. package/src/components/references/ReferenceLine.tsx +43 -0
  67. package/src/components/references/ReferenceSearch.tsx +163 -0
  68. package/src/components/references/ReferenceSearchResults.tsx +113 -0
  69. package/src/components/references/ReferenceSearchResultsPlaceholder.tsx +71 -0
  70. package/src/components/references/ReferenceSearchSection.tsx +124 -0
  71. package/src/components/references/ReferencesEditor.tsx +61 -0
  72. package/src/components/references/ReferencesModal.tsx +352 -0
  73. package/src/components/references/SearchInput.tsx +98 -0
  74. package/src/components/toolbar/InsertEmbedDialog.tsx +222 -0
  75. package/src/components/toolbar/InsertTableDialog.tsx +208 -0
  76. package/src/components/toolbar/ListMenuItem.tsx +203 -0
  77. package/src/components/toolbar/helpers.ts +547 -0
  78. package/src/components/toolbar/type-selector/OptionComponent.tsx +89 -0
  79. package/src/components/toolbar/type-selector/TypeSelector.tsx +157 -0
  80. package/src/components/toolbar/type-selector/styles.ts +79 -0
  81. package/src/components/views/CrossReferenceItems.tsx +199 -0
  82. package/src/components/views/DeleteEmbedDialog.tsx +83 -0
  83. package/src/components/views/DeleteFootnoteDialog.tsx +54 -0
  84. package/src/components/views/FigureDropdown.tsx +423 -0
  85. package/src/components/views/FootnotesSelector.tsx +255 -0
  86. package/src/components/views/InsertSpecialCharacter.tsx +245 -0
  87. package/src/components/views/LinkForm.tsx +220 -0
  88. package/src/components/views/TableCellContextMenu.tsx +241 -0
  89. package/src/configs/ManuscriptsEditor.ts +140 -0
  90. package/src/configs/editor-plugins.ts +119 -0
  91. package/src/configs/editor-views.ts +139 -0
  92. package/src/icons.ts +62 -0
  93. package/src/index.ts +65 -0
  94. package/src/keys/highlight.ts +65 -0
  95. package/src/keys/index.ts +33 -0
  96. package/src/keys/keyword.ts +69 -0
  97. package/src/keys/list.ts +156 -0
  98. package/src/keys/misc.ts +112 -0
  99. package/src/keys/title.ts +221 -0
  100. package/src/lib/__tests__/__fixtures__/doc.json +388 -0
  101. package/src/lib/__tests__/__snapshots__/paste.test.ts.snap +24 -0
  102. package/src/lib/__tests__/authors.test.ts +202 -0
  103. package/src/lib/__tests__/helpers.test.ts +46 -0
  104. package/src/lib/__tests__/paste.test.ts +57 -0
  105. package/src/lib/__tests__/plugins.test.ts +176 -0
  106. package/src/lib/__tests__/url.test.ts +31 -0
  107. package/src/lib/array-reducer.ts +68 -0
  108. package/src/lib/authors-and-affiliations.ts +81 -0
  109. package/src/lib/authors.ts +67 -0
  110. package/src/lib/capabilities.ts +55 -0
  111. package/src/lib/codemirror.ts +37 -0
  112. package/src/lib/comments.ts +123 -0
  113. package/src/lib/context-menu.ts +745 -0
  114. package/src/lib/copy.ts +30 -0
  115. package/src/lib/crossref.ts +90 -0
  116. package/src/lib/dnd.ts +29 -0
  117. package/src/lib/doc.ts +167 -0
  118. package/src/lib/dompurify.ts +28 -0
  119. package/src/lib/files.ts +180 -0
  120. package/src/lib/footnotes.ts +83 -0
  121. package/src/lib/get-media-type.ts +105 -0
  122. package/src/lib/helpers.ts +199 -0
  123. package/src/lib/hierarchy.ts +117 -0
  124. package/src/lib/languages.ts +37 -0
  125. package/src/lib/lists.ts +56 -0
  126. package/src/lib/math.ts +111 -0
  127. package/src/lib/media.ts +334 -0
  128. package/src/lib/navigation-utils.ts +235 -0
  129. package/src/lib/normalize.ts +70 -0
  130. package/src/lib/paste.ts +304 -0
  131. package/src/lib/placeholder.ts +32 -0
  132. package/src/lib/platform.ts +18 -0
  133. package/src/lib/plugins.ts +22 -0
  134. package/src/lib/popper.ts +180 -0
  135. package/src/lib/position-menu.ts +184 -0
  136. package/src/lib/references.ts +94 -0
  137. package/src/lib/template.ts +29 -0
  138. package/src/lib/track-changes-utils.ts +34 -0
  139. package/{dist/types/lib/statistics.d.ts → src/lib/url.ts} +11 -8
  140. package/src/lib/use-do-with-debounce.ts +39 -0
  141. package/src/lib/utils.ts +323 -0
  142. package/src/lib/view.ts +100 -0
  143. package/src/menus.tsx +684 -0
  144. package/src/node-type-icons.tsx +83 -0
  145. package/src/plugins/__tests__/__fixtures__/deleted-footnote.json +140 -0
  146. package/src/plugins/__tests__/__fixtures__/inserted-footnote.json +153 -0
  147. package/src/plugins/__tests__/footnotes.test.ts +67 -0
  148. package/src/plugins/accessibility_element.ts +219 -0
  149. package/src/plugins/add-subtitle.ts +102 -0
  150. package/src/plugins/affiliations.ts +136 -0
  151. package/src/plugins/alt-titles.ts +219 -0
  152. package/src/plugins/bibliography.ts +235 -0
  153. package/src/plugins/comments.ts +328 -0
  154. package/src/plugins/cross-references.ts +70 -0
  155. package/src/plugins/detect-inconsistency/detect-inconsistency-utils.ts +102 -0
  156. package/src/plugins/detect-inconsistency/index.ts +55 -0
  157. package/src/plugins/detect-inconsistency/validators.ts +283 -0
  158. package/src/plugins/doi.ts +66 -0
  159. package/src/plugins/editor-props.ts +39 -0
  160. package/src/plugins/elements.ts +60 -0
  161. package/src/plugins/footnotes.ts +298 -0
  162. package/src/plugins/link.ts +53 -0
  163. package/src/plugins/lock-body.ts +136 -0
  164. package/src/plugins/move-node.ts +55 -0
  165. package/src/plugins/objects.ts +125 -0
  166. package/src/plugins/paragraphs.ts +90 -0
  167. package/src/plugins/persist.ts +64 -0
  168. package/src/plugins/persistent-cursor.ts +66 -0
  169. package/src/plugins/placeholder.ts +219 -0
  170. package/src/plugins/prevent-empty.ts +50 -0
  171. package/src/plugins/search-replace/index.ts +157 -0
  172. package/src/plugins/search-replace/lib.ts +95 -0
  173. package/src/plugins/section_category.ts +212 -0
  174. package/src/plugins/section_title/autocompletion.ts +87 -0
  175. package/src/plugins/section_title/index.ts +105 -0
  176. package/src/plugins/selected-suggestion.ts +243 -0
  177. package/src/plugins/tables-cursor-fix.ts +143 -0
  178. package/src/plugins/translations.ts +263 -0
  179. package/src/rules.ts +60 -0
  180. package/src/selection.ts +112 -0
  181. package/src/testing/default-capabilities.ts +48 -0
  182. package/src/testing/default-editor-data.ts +73 -0
  183. package/src/testing/empty-editor-doc.json +62 -0
  184. package/src/testing/polyfill-dom.ts +43 -0
  185. package/src/testing/section-categories.json +161 -0
  186. package/src/testing/setup-editor.ts +55 -0
  187. package/src/tests.ts +42 -0
  188. package/src/toolbar.tsx +259 -0
  189. package/src/types/@citation-js/core.d.ts +16 -0
  190. package/src/types/@citation-js/index.d.ts +16 -0
  191. package/src/types/@citation-js/plugin-bibtex.d.ts +16 -0
  192. package/src/types/@citation-js/plugin-csl.d.ts +16 -0
  193. package/src/types/@citation-js/plugin-doi.d.ts +16 -0
  194. package/src/types/@citation-js/plugin-enw.d.ts +16 -0
  195. package/src/types/@citation-js/plugin-pubmed.d.ts +16 -0
  196. package/src/types/@citation-js/plugin-ris.d.ts +16 -0
  197. package/src/types/citeproc.d.ts +124 -0
  198. package/src/types/css.d.ts +16 -0
  199. package/src/types/json.d.ts +17 -0
  200. package/src/types/prosemirror-dev-tools.d.ts +16 -0
  201. package/src/types/prosemirror-dropcursor.d.ts +16 -0
  202. package/src/types/styled-components.d.ts +23 -0
  203. package/src/types.ts +49 -0
  204. package/src/useEditor.ts +244 -0
  205. package/src/versions.ts +3 -0
  206. package/src/views/ReactSubView.tsx +145 -0
  207. package/src/views/abstracts.ts +46 -0
  208. package/src/views/accessibility_element.ts +86 -0
  209. package/src/views/affiliations.ts +254 -0
  210. package/src/views/alt_title.ts +85 -0
  211. package/src/views/alt_titles_section.ts +97 -0
  212. package/src/views/attachment.ts +160 -0
  213. package/src/views/attachments.ts +72 -0
  214. package/src/views/author_notes.ts +96 -0
  215. package/src/views/award.ts +194 -0
  216. package/src/views/awards.ts +59 -0
  217. package/src/views/base_node_view.ts +85 -0
  218. package/src/views/bibliography_element.ts +313 -0
  219. package/src/views/block_view.ts +100 -0
  220. package/src/views/blockquote_element.ts +26 -0
  221. package/src/views/blockquote_element_editable.ts +24 -0
  222. package/src/views/box_element.ts +33 -0
  223. package/src/views/caption.ts +37 -0
  224. package/src/views/caption_title.ts +33 -0
  225. package/src/views/citation.ts +67 -0
  226. package/src/views/citation_editable.ts +312 -0
  227. package/src/views/contributors.ts +341 -0
  228. package/src/views/creators.ts +82 -0
  229. package/src/views/cross_reference.ts +74 -0
  230. package/src/views/cross_reference_editable.ts +113 -0
  231. package/src/views/editable_block.ts +141 -0
  232. package/src/views/embed.ts +345 -0
  233. package/src/views/empty.ts +26 -0
  234. package/src/views/equation.ts +47 -0
  235. package/src/views/equation_editable.ts +84 -0
  236. package/src/views/equation_element.ts +29 -0
  237. package/src/views/equation_element_editable.ts +21 -0
  238. package/src/views/figure.ts +84 -0
  239. package/src/views/figure_editable.ts +361 -0
  240. package/src/views/figure_element.ts +197 -0
  241. package/src/views/figure_element_editable.ts +21 -0
  242. package/src/views/footnote.ts +236 -0
  243. package/src/views/footnotes_element.ts +54 -0
  244. package/src/views/general_table_footnote.ts +140 -0
  245. package/src/views/hero_image.ts +76 -0
  246. package/src/views/hero_image_editable.ts +21 -0
  247. package/src/views/image_element.ts +373 -0
  248. package/src/views/image_element_editable.ts +21 -0
  249. package/src/views/inline_equation.ts +47 -0
  250. package/src/views/inline_equation_editable.ts +70 -0
  251. package/src/views/inline_footnote.ts +264 -0
  252. package/src/views/inline_footnote_editable.ts +20 -0
  253. package/src/views/keyword.ts +127 -0
  254. package/src/views/keyword_group.ts +109 -0
  255. package/src/views/link.ts +27 -0
  256. package/src/views/link_editable.ts +169 -0
  257. package/src/views/list.ts +46 -0
  258. package/src/views/list_item.ts +26 -0
  259. package/src/views/paragraph.ts +26 -0
  260. package/src/views/paragraph_editable.ts +21 -0
  261. package/src/views/placeholder.ts +35 -0
  262. package/src/views/placeholder_element.ts +38 -0
  263. package/src/views/placeholder_element_editable.ts +21 -0
  264. package/src/views/pullquote_element.ts +106 -0
  265. package/src/views/pullquote_element_editable.ts +24 -0
  266. package/src/views/quote_image_editable.ts +84 -0
  267. package/src/views/section.ts +64 -0
  268. package/src/views/section_label.ts +20 -0
  269. package/src/views/section_title.ts +87 -0
  270. package/src/views/section_title_editable.ts +21 -0
  271. package/src/views/subtitle.ts +42 -0
  272. package/src/views/subtitle_editable.ts +20 -0
  273. package/src/views/subtitles.ts +34 -0
  274. package/src/views/subtitles_editable.ts +21 -0
  275. package/src/views/supplement.ts +236 -0
  276. package/src/views/supplement_editable.ts +20 -0
  277. package/src/views/supplements.ts +65 -0
  278. package/src/views/supplements_editable.ts +21 -0
  279. package/src/views/table_cell.ts +150 -0
  280. package/src/views/table_element.ts +33 -0
  281. package/src/views/table_element_editable.ts +21 -0
  282. package/src/views/table_element_footer.ts +41 -0
  283. package/src/views/title.ts +46 -0
  284. package/src/views/title_editable.ts +20 -0
  285. package/src/views/trans_graphical_abstract.ts +55 -0
  286. package/src/views/trans_graphical_abstract_editable.ts +21 -0
  287. package/src/views/translated_abstract.ts +53 -0
  288. package/src/views/translated_abstract_editable.ts +21 -0
  289. package/dist/cjs/lib/statistics.js +0 -38
@@ -0,0 +1,244 @@
1
+ /*!
2
+ * © 2019 Atypon Systems LLC
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import {
18
+ trackChangesPluginKey,
19
+ TrackChangesStatus,
20
+ } from '@manuscripts/track-changes-plugin'
21
+ import {
22
+ getVersion,
23
+ receiveTransaction,
24
+ sendableSteps,
25
+ } from 'prosemirror-collab'
26
+ import {
27
+ Command,
28
+ EditorState,
29
+ TextSelection,
30
+ Transaction,
31
+ } from 'prosemirror-state'
32
+ import { EditorView } from 'prosemirror-view'
33
+ import { useCallback, useEffect, useRef, useState } from 'react'
34
+ import { useLocation } from 'react-router-dom'
35
+
36
+ import {
37
+ createEditorState,
38
+ createEditorView,
39
+ ExternalProps,
40
+ } from './configs/ManuscriptsEditor'
41
+ import { PopperManager } from './lib/popper'
42
+ import { useDoWithDebounce } from './lib/use-do-with-debounce'
43
+ import { selectionForOutlineNavigation } from './lib/helpers'
44
+ import { searchReplaceKey } from './plugins/search-replace'
45
+
46
+ export const useEditor = (externalProps: ExternalProps) => {
47
+ const view = useRef<EditorView>(undefined)
48
+
49
+ const props = { ...externalProps, popper: new PopperManager() }
50
+
51
+ const [state, setState] = useState<EditorState>(() =>
52
+ createEditorState(props)
53
+ )
54
+ const location = useLocation()
55
+ const { collabProvider } = props
56
+
57
+ // Update editor state when document changes (e.g., when switching to comparison mode)
58
+ useEffect(() => {
59
+ if (view.current && props.isComparingMode) {
60
+ const newState = createEditorState(props)
61
+ setState(newState)
62
+ view.current.updateState(newState)
63
+ }
64
+ // eslint-disable-next-line react-hooks/exhaustive-deps
65
+ }, [props.doc, props.isComparingMode])
66
+
67
+ useEffect(() => {
68
+ // Receiving steps from backend
69
+ if (collabProvider && !props.isComparingMode) {
70
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
71
+ collabProvider.onNewSteps(async () => {
72
+ if (state && view.current) {
73
+ let localVersion = getVersion(view.current.state)
74
+ const since = await collabProvider.stepsSince(
75
+ getVersion(view.current.state)
76
+ )
77
+
78
+ /*
79
+ Check if we already requested and applied steps for this version before. Duplicate request for the same version can happen
80
+ when websocket signals that there are new steps at about the same time when we send some new steps and get 409 as a response
81
+ due to conflict with the very same steps in authority. It would result in double request and application of the same steps and
82
+ forever desync (until page reload that is)
83
+ */
84
+ localVersion = getVersion(view.current.state)
85
+ if (since && since.version <= localVersion) {
86
+ return
87
+ }
88
+
89
+ if (since?.steps.length && since.clientIDs.length) {
90
+ view.current.dispatch(
91
+ receiveTransaction(
92
+ // has to be called for the collab to increment version and drop buffered steps
93
+ view.current.state,
94
+ since?.steps,
95
+ since.clientIDs
96
+ )
97
+ )
98
+ } else {
99
+ console.warn('Inconsistent new steps event from the authority.')
100
+ }
101
+ }
102
+ })
103
+ }
104
+ return () => {
105
+ collabProvider?.unsubscribe()
106
+ }
107
+ }, [collabProvider, props.isComparingMode, !!view.current]) // eslint-disable-line react-hooks/exhaustive-deps
108
+
109
+ const debounce = useDoWithDebounce()
110
+
111
+ const dispatch = useCallback(
112
+ (tr: Transaction) => {
113
+ if (!view.current) {
114
+ return state
115
+ }
116
+
117
+ const nextState = view.current.state.apply(tr)
118
+ view.current.updateState(nextState)
119
+
120
+ const trackState = trackChangesPluginKey.getState(view.current.state)
121
+
122
+ if (
123
+ collabProvider &&
124
+ (!trackState ||
125
+ trackState.status !== TrackChangesStatus.viewSnapshots) &&
126
+ !props.isComparingMode
127
+ ) {
128
+ const sendable = sendableSteps(nextState)
129
+
130
+ if (sendable) {
131
+ collabProvider.sendSteps(
132
+ sendable.version,
133
+ sendable.steps,
134
+ sendable.clientID,
135
+ false
136
+ )
137
+ }
138
+ }
139
+ debounce(
140
+ () => {
141
+ setState(nextState)
142
+ },
143
+ 250,
144
+ !tr.isGeneric || !tr.docChanged || !tr.getMeta(searchReplaceKey)
145
+ )
146
+
147
+ return nextState
148
+ },
149
+ [] // eslint-disable-line react-hooks/exhaustive-deps
150
+ )
151
+
152
+ const isViewingMode = props.isViewingMode
153
+
154
+ const onRender = useCallback(
155
+ (el: HTMLDivElement | null) => {
156
+ if (view.current) {
157
+ view.current.destroy()
158
+ view.current = undefined
159
+ }
160
+
161
+ if (!el) {
162
+ return
163
+ }
164
+
165
+ const freshState = createEditorState(props)
166
+ view.current = createEditorView(props, el, freshState || state, dispatch)
167
+ setState(view.current.state)
168
+ },
169
+ [isViewingMode] // eslint-disable-line react-hooks/exhaustive-deps
170
+ )
171
+
172
+ const isCommandValid = useCallback(
173
+ (command: Command): boolean => command(state),
174
+ [state]
175
+ )
176
+
177
+ const doCommand = useCallback(
178
+ (command: Command): boolean => command(state, dispatch, view.current),
179
+ [state, dispatch]
180
+ )
181
+
182
+ const replaceState = useCallback((state: EditorState) => {
183
+ setState(state)
184
+ if (view.current) {
185
+ view.current.updateState(state)
186
+ }
187
+ }, [])
188
+
189
+ const focusNodeWithId = useCallback(
190
+ (id: string) => {
191
+ const currentView = view.current
192
+ if (!id || !currentView || !state) {
193
+ return
194
+ }
195
+
196
+ const viewState = currentView.state
197
+ viewState.doc.descendants((node, pos) => {
198
+ if (node.attrs.id === id) {
199
+ currentView.focus()
200
+
201
+ const selection = selectionForOutlineNavigation(viewState.doc, pos)
202
+
203
+ currentView.dispatch(viewState.tr.setSelection(selection))
204
+
205
+ const scrollPos =
206
+ selection instanceof TextSelection ? selection.from : pos + 1
207
+ const dom = currentView.domAtPos(scrollPos)
208
+
209
+ if (dom.node instanceof Element) {
210
+ dom.node.scrollIntoView({
211
+ behavior: 'smooth',
212
+ block: 'start',
213
+ inline: 'nearest',
214
+ })
215
+ }
216
+
217
+ return false
218
+ }
219
+ })
220
+ },
221
+ [state]
222
+ )
223
+
224
+ useEffect(() => {
225
+ // This will be evaluated on every route change. So, if
226
+ // the route has changed and the node id is defined, we want to
227
+ // focus that node.
228
+ const nodeId = location.hash.substring(1)
229
+ if (nodeId) {
230
+ focusNodeWithId(nodeId)
231
+ }
232
+ // eslint-disable-next-line react-hooks/exhaustive-deps
233
+ }, [location])
234
+
235
+ return {
236
+ state,
237
+ onRender,
238
+ isCommandValid,
239
+ doCommand,
240
+ replaceState,
241
+ view: view.current,
242
+ dispatch,
243
+ }
244
+ }
@@ -0,0 +1,3 @@
1
+ //THIS FILE WAS GENERATED BY versions.mjs
2
+ export const VERSION = '3.13.1';
3
+ export const MATHJAX_VERSION = '3.2.2';
@@ -0,0 +1,145 @@
1
+ /*!
2
+ * © 2019 Atypon Systems LLC
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import { ManuscriptEditorView, ManuscriptNode } from '@manuscripts/transform'
18
+ import React from 'react'
19
+ import { flushSync } from 'react-dom'
20
+ import { createRoot } from 'react-dom/client'
21
+ import { ThemeProvider } from 'styled-components'
22
+
23
+ import { EditorProps } from '../configs/ManuscriptsEditor'
24
+ import { Trackable } from '../types'
25
+
26
+ export interface ReactViewComponentProps<NodeT extends ManuscriptNode> {
27
+ nodeAttrs: NodeT['attrs']
28
+ setNodeAttrs: (nextAttrs: Partial<NodeT['attrs']>) => void
29
+ viewProps: {
30
+ view: ManuscriptEditorView
31
+ getPos: () => number
32
+ node: ManuscriptNode | Trackable<ManuscriptNode>
33
+ }
34
+ container: HTMLDivElement
35
+ }
36
+ /*
37
+ This is to render components that affect the Prosemirror Document indirectly. Such as dropdown buttons, inputs, advanced UX elements etc.
38
+ MAKE SURE dispatch IS PASSED TO YOUR VIEW
39
+ */
40
+ function createSubView<T extends Trackable<ManuscriptNode>>(
41
+ props: EditorProps,
42
+ Component: React.FC<any>, // eslint-disable-line @typescript-eslint/no-explicit-any
43
+ componentProps: object,
44
+ node: T,
45
+ getPos: () => number,
46
+ view: ManuscriptEditorView,
47
+ classNames: string[] = []
48
+ ): HTMLDivElement {
49
+ const container = document.createElement('div')
50
+ const Wrapped = createView<T>(
51
+ props,
52
+ Component,
53
+ componentProps,
54
+ node,
55
+ getPos,
56
+ view,
57
+ classNames,
58
+ container
59
+ )
60
+ const root = createRoot(container)
61
+ root.render(<Wrapped />)
62
+ return container
63
+ }
64
+
65
+ function createView<T extends Trackable<ManuscriptNode>>(
66
+ props: EditorProps,
67
+ Component: React.FC<any>, // eslint-disable-line @typescript-eslint/no-explicit-any
68
+ componentProps: object,
69
+ node: T,
70
+ getPos: () => number,
71
+ view: ManuscriptEditorView,
72
+ classNames: string[] = [],
73
+ container: HTMLDivElement
74
+ ) {
75
+ container.classList.add('tools-panel')
76
+ if (classNames.length) {
77
+ container.classList.add(...classNames)
78
+ container.setAttribute('data-cy', classNames[0])
79
+ }
80
+ container.setAttribute('contenteditable', 'false')
81
+
82
+ const Wrapped: React.FC = () => {
83
+ const setNodeAttrs = (nextAttrs: Partial<ManuscriptNode['attrs']>) => {
84
+ const { selection, tr } = view.state
85
+
86
+ tr.setNodeMarkup(getPos(), undefined, {
87
+ ...node.attrs,
88
+ ...nextAttrs,
89
+ }).setSelection(selection.map(tr.doc, tr.mapping))
90
+
91
+ view.dispatch(tr)
92
+ }
93
+
94
+ return (
95
+ <ThemeProvider theme={props.theme}>
96
+ <Component
97
+ nodeAttrs={node.attrs}
98
+ setNodeAttrs={setNodeAttrs}
99
+ viewProps={{ node, view, getPos }}
100
+ container={container}
101
+ {...props}
102
+ {...componentProps}
103
+ />
104
+ </ThemeProvider>
105
+ )
106
+ }
107
+ return Wrapped
108
+ }
109
+
110
+ /**
111
+ * Due to async rendering in React, inline or persistent elements may flicker during rerendering.
112
+ * To prevent that this wrapper allows to replace element with its new version only when it's already rendered.
113
+ */
114
+ export function createSubViewAsync<T extends Trackable<ManuscriptNode>>(
115
+ props: EditorProps,
116
+ Component: React.FC<any>, // eslint-disable-line @typescript-eslint/no-explicit-any
117
+ componentProps: object,
118
+ node: T,
119
+ getPos: () => number,
120
+ view: ManuscriptEditorView,
121
+ classNames: string[] = []
122
+ ): Promise<HTMLDivElement> {
123
+ const container = document.createElement('div')
124
+ const Wrapped = createView<T>(
125
+ props,
126
+ Component,
127
+ componentProps,
128
+ node,
129
+ getPos,
130
+ view,
131
+ classNames,
132
+ container
133
+ )
134
+
135
+ const root = createRoot(container)
136
+
137
+ return new Promise<HTMLDivElement>((resolve) => {
138
+ flushSync(() => {
139
+ root.render(<Wrapped />)
140
+ })
141
+ resolve(container)
142
+ })
143
+ }
144
+
145
+ export default createSubView
@@ -0,0 +1,46 @@
1
+ /*!
2
+ * © 2025 Atypon Systems LLC
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import { ManuscriptNode } from '@manuscripts/transform'
18
+
19
+ import { BaseNodeView } from './base_node_view'
20
+ import { createNodeView } from './creators'
21
+
22
+ export class AbstractsView extends BaseNodeView<ManuscriptNode> {
23
+ public elementType = 'div'
24
+
25
+ public initialise() {
26
+ this.createDOM()
27
+ this.createElement()
28
+ this.updateContents()
29
+ }
30
+
31
+ public createDOM() {
32
+ this.dom = document.createElement(this.elementType)
33
+ this.dom.classList.add('abstracts')
34
+ }
35
+
36
+ public createElement() {
37
+ this.contentDOM = document.createElement(this.elementType)
38
+ this.dom.appendChild(this.contentDOM)
39
+ }
40
+
41
+ public updateContents() {
42
+ super.updateContents()
43
+ }
44
+ }
45
+
46
+ export default createNodeView(AbstractsView)
@@ -0,0 +1,86 @@
1
+ /*!
2
+ * © 2025 Atypon Systems LLC
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ import { LongDescNode, schema } from '@manuscripts/transform'
17
+ import { TextSelection } from 'prosemirror-state'
18
+
19
+ import { createKeyboardInteraction } from '../lib/navigation-utils'
20
+ import BlockView from './block_view'
21
+ import { createNodeView } from './creators'
22
+ export class AccessibilityElementView extends BlockView<LongDescNode> {
23
+ public contentDOM: HTMLElement
24
+ private removeKeydownListener?: () => void
25
+
26
+ public initialise() {
27
+ this.createDOM()
28
+ this.createElement()
29
+ this.updateContents()
30
+ }
31
+
32
+ public createDOM() {
33
+ this.dom = document.createElement('div')
34
+ this.dom.classList.add('accessibility_element')
35
+ const label = document.createElement('div')
36
+ label.contentEditable = 'false'
37
+ label.className = 'accessibility_element_label'
38
+ label.innerText =
39
+ this.node.type === schema.nodes.long_desc
40
+ ? 'Long description'
41
+ : 'Alt text'
42
+ this.dom.appendChild(label)
43
+ }
44
+
45
+ public createElement() {
46
+ super.createElement()
47
+ this.contentDOM.className = 'accessibility_element_input'
48
+ this.contentDOM.setAttribute('contenteditable', 'true')
49
+
50
+ this.contentDOM.tabIndex = this.node.type === schema.nodes.alt_text ? 0 : -1
51
+
52
+ this.removeKeydownListener = createKeyboardInteraction({
53
+ container: this.contentDOM,
54
+ navigation: {
55
+ getItems: () => {
56
+ const parentEl = this.dom.parentElement
57
+ if (!parentEl) {
58
+ return []
59
+ }
60
+ return Array.from(
61
+ parentEl.querySelectorAll('.accessibility_element_input')
62
+ ) as HTMLElement[]
63
+ },
64
+ arrowKeys: { forward: 'ArrowDown', backward: 'ArrowUp' },
65
+ getCurrentElement: () => this.contentDOM,
66
+ },
67
+ additionalKeys: {
68
+ Enter: (e) => {
69
+ e.preventDefault()
70
+ const pos = this.getPos()
71
+ const tr = this.view.state.tr.setSelection(
72
+ TextSelection.create(this.view.state.doc, pos + 1)
73
+ )
74
+ this.view.dispatch(tr)
75
+ this.view.focus()
76
+ },
77
+ },
78
+ })
79
+ }
80
+ public destroy() {
81
+ this.removeKeydownListener?.()
82
+ super.destroy()
83
+ }
84
+ }
85
+
86
+ export default createNodeView(AccessibilityElementView)