@manuscripts/body-editor 3.12.66 → 3.13.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 (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,313 @@
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 { ContextMenu, ContextMenuProps } from '@manuscripts/style-guide'
18
+ import {
19
+ BibliographyElementNode,
20
+ BibliographyItemAttrs,
21
+ BibliographyItemNode,
22
+ schema,
23
+ } from '@manuscripts/transform'
24
+ import { NodeSelection } from 'prosemirror-state'
25
+
26
+ import {
27
+ ReferencesEditor,
28
+ ReferencesEditorProps,
29
+ } from '../components/references/ReferencesEditor'
30
+ import { CommentKey, createCommentMarker, handleComment } from '../lib/comments'
31
+ import { handleEnterKey } from '../lib/navigation-utils'
32
+ import { findNodeByID } from '../lib/doc'
33
+ import { sanitize } from '../lib/dompurify'
34
+
35
+ import { deleteNode, findChildByID, updateNodeAttrs } from '../lib/view'
36
+ import { getBibliographyPluginState } from '../plugins/bibliography'
37
+ import { commentsKey, setCommentSelection } from '../plugins/comments'
38
+ import { selectedSuggestionKey } from '../plugins/selected-suggestion'
39
+ import { Trackable } from '../types'
40
+ import BlockView from './block_view'
41
+ import { createNodeView } from './creators'
42
+ import ReactSubView from './ReactSubView'
43
+ import {
44
+ addTrackChangesAttributes,
45
+ addTrackChangesClassNames,
46
+ } from '@manuscripts/track-changes-plugin'
47
+
48
+ export class BibliographyElementBlockView extends BlockView<
49
+ Trackable<BibliographyElementNode>
50
+ > {
51
+ private container: HTMLElement
52
+ private editor: HTMLDivElement
53
+ private contextMenu: HTMLDivElement
54
+ private version: string
55
+
56
+ public showPopper(id: string) {
57
+ const bib = getBibliographyPluginState(this.view.state)
58
+ if (!bib) {
59
+ return
60
+ }
61
+
62
+ const componentProps: ReferencesEditorProps = {
63
+ items: Array.from(bib.bibliographyItems.values()),
64
+ citationCounts: bib.citationCounts,
65
+ item: bib.bibliographyItems.get(id),
66
+ onSave: this.handleSave,
67
+ onDelete: this.handleDelete,
68
+ }
69
+
70
+ this.editor = ReactSubView(
71
+ this.props,
72
+ ReferencesEditor,
73
+ componentProps,
74
+ this.node,
75
+ this.getPos,
76
+ this.view,
77
+ ['references-editor']
78
+ )
79
+
80
+ this.props.popper.show(this.dom, this.editor, 'right')
81
+ }
82
+
83
+ public stopEvent = () => true
84
+ public ignoreMutation = () => true
85
+
86
+ private handleEdit(citationID: string) {
87
+ this.showPopper(citationID)
88
+ }
89
+
90
+ private showContextMenu(element: HTMLElement) {
91
+ this.props.popper.destroy()
92
+ const can = this.props.getCapabilities()
93
+ const item = findNodeByID(this.view.state.doc, element.id)?.node
94
+
95
+ const componentProps: ContextMenuProps = {
96
+ actions: [],
97
+ }
98
+ if (can.editCitationsAndRefs) {
99
+ componentProps.actions.push({
100
+ label: 'Edit',
101
+ action: () => this.handleEdit(element.id),
102
+ icon: 'Edit',
103
+ })
104
+ }
105
+ componentProps.actions.push({
106
+ label: 'Comment',
107
+ action: () => handleComment(item, this.view),
108
+ icon: 'AddComment',
109
+ })
110
+
111
+ this.contextMenu = ReactSubView(
112
+ this.props,
113
+ ContextMenu,
114
+ componentProps,
115
+ this.node,
116
+ this.getPos,
117
+ this.view,
118
+ ['context-menu']
119
+ )
120
+ this.props.popper.show(element, this.contextMenu, 'right-start')
121
+ }
122
+
123
+ private handleCommentMarkerInteraction = (marker: HTMLElement) => {
124
+ const key = marker.dataset.key as CommentKey
125
+ const tr = this.view.state.tr
126
+ setCommentSelection(tr, key, undefined, false)
127
+ this.view.dispatch(tr)
128
+ }
129
+
130
+ private handleBibItemInteraction = (item: HTMLElement) => {
131
+ if (!this.props.getCapabilities().seeReferencesButtons) {
132
+ return
133
+ }
134
+
135
+ this.showContextMenu(item)
136
+ const node = findChildByID(this.view, item.id)
137
+ if (node) {
138
+ const tr = this.view.state.tr
139
+ tr.setSelection(NodeSelection.create(this.view.state.doc, node.pos))
140
+ this.view.dispatch(tr)
141
+ }
142
+ }
143
+
144
+ private handleClick = (event: Event) => {
145
+ const element = event.target as HTMLElement
146
+ // Handle click on comment marker
147
+ const marker = element.closest('.comment-marker') as HTMLElement
148
+ if (marker) {
149
+ this.handleCommentMarkerInteraction(marker)
150
+ return
151
+ }
152
+
153
+ // Handle click on bib-item
154
+ const item = element.closest('.bib-item')
155
+ if (item) {
156
+ this.handleBibItemInteraction(item as HTMLElement)
157
+ }
158
+ }
159
+
160
+ private handleKeyDown = (event: KeyboardEvent) => {
161
+ handleEnterKey(() => {
162
+ const target = document.activeElement as HTMLElement
163
+ // Handle Enter on comment marker
164
+ const marker = target?.closest('.comment-marker') as HTMLElement
165
+ if (marker) {
166
+ this.handleCommentMarkerInteraction(marker)
167
+ return
168
+ }
169
+
170
+ // Handle Enter on bib-item
171
+ const bibItem = target?.closest('.bib-item') as HTMLElement
172
+ if (bibItem) {
173
+ this.handleBibItemInteraction(bibItem)
174
+ }
175
+ })(event)
176
+ }
177
+
178
+ public updateContents() {
179
+ this.props.popper.destroy() // destroy the old context menu
180
+ const bib = getBibliographyPluginState(this.view.state)
181
+ if (!bib) {
182
+ return
183
+ }
184
+
185
+ if (bib.version === this.version) {
186
+ this.updateSelections()
187
+ return
188
+ }
189
+ this.version = bib.version
190
+
191
+ const nodes: Map<string, BibliographyItemNode> = new Map()
192
+
193
+ this.node.descendants((node) => {
194
+ const id = node.attrs.id
195
+ nodes.set(id, node as BibliographyItemNode)
196
+ })
197
+
198
+ const wrapper = document.createElement('div')
199
+ wrapper.classList.add('contents')
200
+ wrapper.addEventListener('click', this.handleClick)
201
+ wrapper.addEventListener('keydown', this.handleKeyDown)
202
+
203
+ const [meta, bibliography] = bib.engine.makeBibliography()
204
+
205
+ for (let i = 0; i < bibliography.length; i++) {
206
+ const id = meta.entry_ids[i][0]
207
+ const fragment = bibliography[i]
208
+ const node = nodes.get(id) as BibliographyItemNode
209
+ const isUnstructured = node.attrs.type === 'literal'
210
+
211
+ const tempDiv = document.createElement('div')
212
+ tempDiv.innerHTML = fragment
213
+
214
+ if (isUnstructured) {
215
+ const cslLeftMarginDiv = tempDiv.querySelector('.csl-left-margin')
216
+ let cslRightInlineDiv = tempDiv.querySelector('.csl-right-inline')
217
+ const cslEntry = tempDiv.querySelector('.csl-entry')
218
+
219
+ if (cslRightInlineDiv) {
220
+ // Overwrite existing inline content
221
+ cslRightInlineDiv.textContent = node.attrs.literal ?? ''
222
+ } else if (cslLeftMarginDiv) {
223
+ // Right inline missing, but left margin present — add right inline after it
224
+ cslRightInlineDiv = document.createElement('div')
225
+ cslRightInlineDiv.classList.add('csl-right-inline')
226
+ cslRightInlineDiv.textContent = node.attrs.literal ?? ''
227
+ cslLeftMarginDiv.after(cslRightInlineDiv)
228
+ } else if (cslEntry) {
229
+ // No left/right structure — overwrite the entry element content
230
+ cslEntry.textContent = node.attrs.literal ?? ''
231
+ }
232
+ }
233
+
234
+ const element = sanitize(
235
+ `<div id="${id}" class="bib-item"><div class="csl-bib-body">${tempDiv.innerHTML}</div></div>`
236
+ ).firstElementChild as HTMLElement
237
+
238
+ element.tabIndex = 0
239
+
240
+ const comment = createCommentMarker('div', id)
241
+ element.prepend(comment)
242
+
243
+ addTrackChangesAttributes(node.attrs, element)
244
+ addTrackChangesClassNames(node.attrs, element)
245
+
246
+ wrapper.append(element)
247
+ }
248
+
249
+ if (!bibliography.length) {
250
+ this.dom.classList.add('empty-node')
251
+ } else {
252
+ this.dom.classList.remove('empty-node')
253
+ }
254
+
255
+ const oldContent = this.container.querySelector('.contents')
256
+ if (oldContent) {
257
+ this.container.replaceChild(wrapper, oldContent)
258
+ } else {
259
+ this.container.appendChild(wrapper)
260
+ }
261
+ this.updateSelections()
262
+ }
263
+
264
+ public createElement = () => {
265
+ this.container = document.createElement('div')
266
+ this.container.classList.add('block')
267
+ this.container.contentEditable = 'false'
268
+ this.dom.setAttribute('contenteditable', 'false')
269
+ this.dom.appendChild(this.container)
270
+ }
271
+
272
+ private handleSave = (attrs: BibliographyItemAttrs) => {
273
+ updateNodeAttrs(this.view, schema.nodes.bibliography_item, attrs)
274
+ }
275
+
276
+ private handleDelete = (item: BibliographyItemAttrs) => {
277
+ deleteNode(this.view, item.id)
278
+ }
279
+
280
+ private updateSelections = () => {
281
+ const state = this.view.state
282
+ const com = commentsKey.getState(state)
283
+ const suggestion = selectedSuggestionKey.getState(state)?.suggestion
284
+
285
+ const items = this.container.querySelectorAll('.bib-item')
286
+ items.forEach((e) => {
287
+ const item = e as HTMLElement
288
+ if (suggestion?.id && item.dataset.trackId === suggestion?.id) {
289
+ item.classList.add('selected-suggestion')
290
+ } else {
291
+ item.classList.remove('selected-suggestion')
292
+ }
293
+
294
+ const marker = item.querySelector('.comment-marker') as HTMLElement
295
+ const key = marker.dataset.key as CommentKey
296
+ const comments = com?.commentsByKey.get(key)
297
+ if (!comments) {
298
+ marker.setAttribute('data-count', '0')
299
+ } else if (comments.length !== 1) {
300
+ marker.setAttribute('data-count', String(comments.length))
301
+ } else {
302
+ marker.removeAttribute('data-count')
303
+ }
304
+ if (key === com?.selection?.key) {
305
+ marker.classList.add('selected-comment')
306
+ } else {
307
+ marker.classList.remove('selected-comment')
308
+ }
309
+ })
310
+ }
311
+ }
312
+
313
+ export default createNodeView(BibliographyElementBlockView)
@@ -0,0 +1,100 @@
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 { ManuscriptNode, ManuscriptNodeView } from '@manuscripts/transform'
18
+
19
+ import { BaseNodeView } from './base_node_view'
20
+ import { addTrackChangesAttributes } from '@manuscripts/track-changes-plugin'
21
+
22
+ export default class BlockView<BlockNode extends ManuscriptNode>
23
+ extends BaseNodeView<BlockNode>
24
+ implements ManuscriptNodeView
25
+ {
26
+ public initialise() {
27
+ this.createDOM()
28
+ this.createGutter('block-gutter', this.gutterButtons().filter(Boolean))
29
+ this.createElement()
30
+ this.updateContents()
31
+ }
32
+
33
+ public updateContents() {
34
+ this.createGutter(
35
+ 'action-gutter',
36
+ this.actionGutterButtons().filter(Boolean)
37
+ )
38
+ super.updateContents()
39
+ this.updateClasses()
40
+ this.updatePlaceholder()
41
+ }
42
+
43
+ handleTrackChanges() {
44
+ addTrackChangesAttributes(this.node.attrs, this.dom)
45
+ }
46
+
47
+ public updateClasses() {
48
+ if (!this.contentDOM) {
49
+ return
50
+ }
51
+ this.contentDOM.classList.toggle('empty-node', !this.node.childCount)
52
+ }
53
+
54
+ public updatePlaceholder() {
55
+ if (!this.contentDOM) {
56
+ return
57
+ }
58
+ if (this.node.attrs.placeholder) {
59
+ this.contentDOM.dataset.placeholder = this.node.attrs.placeholder
60
+ }
61
+ }
62
+
63
+ public createElement() {
64
+ this.contentDOM = document.createElement(this.elementType)
65
+ this.contentDOM.className = 'block'
66
+ this.dom.appendChild(this.contentDOM)
67
+ }
68
+
69
+ public createDOM() {
70
+ this.dom = document.createElement('div')
71
+ this.dom.classList.add('block-container')
72
+ this.dom.classList.add(`block-${this.node.type.name}`)
73
+ }
74
+
75
+ gutter: Record<string, HTMLElement> = {}
76
+
77
+ public createGutter(className: string, buttons: HTMLElement[]) {
78
+ if (this.gutter[className]) {
79
+ this.gutter[className].remove()
80
+ }
81
+ this.gutter[className] = document.createElement('div')
82
+ this.gutter[className].setAttribute('contenteditable', 'false')
83
+ this.gutter[className].classList.add(className)
84
+
85
+ for (const button of buttons) {
86
+ this.gutter[className].appendChild(button)
87
+ }
88
+
89
+ this.dom.appendChild(this.gutter[className])
90
+ }
91
+
92
+ public gutterButtons(): HTMLElement[] {
93
+ // this to avoid issue of LEAN-4986, as with empty gutter text cursor will sink if that view was empty and has contenteditable as false
94
+ return [document.createElement('div')]
95
+ }
96
+
97
+ public actionGutterButtons(): HTMLElement[] {
98
+ return []
99
+ }
100
+ }
@@ -0,0 +1,26 @@
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 { BlockquoteElementNode } from '@manuscripts/transform'
18
+
19
+ import BlockView from './block_view'
20
+ import { createNodeOrElementView } from './creators'
21
+
22
+ export class BlockquoteElementView extends BlockView<BlockquoteElementNode> {
23
+ public elementType = 'blockquote'
24
+ }
25
+
26
+ export default createNodeOrElementView(BlockquoteElementView, 'blockquote')
@@ -0,0 +1,24 @@
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 { BlockquoteElementView } from './blockquote_element'
18
+ import { createNodeOrElementView } from './creators'
19
+ import { EditableBlock } from './editable_block'
20
+
21
+ export default createNodeOrElementView(
22
+ EditableBlock(BlockquoteElementView),
23
+ 'blockquote'
24
+ )
@@ -0,0 +1,33 @@
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 { BoxElementNode } from '@manuscripts/transform'
18
+
19
+ import BlockView from './block_view'
20
+ import { createNodeView } from './creators'
21
+
22
+ export class BoxElementView extends BlockView<BoxElementNode> {
23
+ public elementType = 'div'
24
+
25
+ public createElement = () => {
26
+ this.contentDOM = document.createElement(this.elementType)
27
+ this.contentDOM.className = 'block box-element'
28
+ this.contentDOM.setAttribute('id', this.node.attrs.id)
29
+ this.dom.appendChild(this.contentDOM)
30
+ }
31
+ }
32
+
33
+ export default createNodeView(BoxElementView)
@@ -0,0 +1,37 @@
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 { CaptionNode, ManuscriptNodeView } from '@manuscripts/transform'
18
+
19
+ import { BaseNodeView } from './base_node_view'
20
+ import { createNodeView } from './creators'
21
+
22
+ export class CaptionView
23
+ extends BaseNodeView<CaptionNode>
24
+ implements ManuscriptNodeView
25
+ {
26
+ public initialise = () => {
27
+ this.createDOM()
28
+ }
29
+ protected createDOM() {
30
+ this.dom = document.createElement('caption')
31
+ this.dom.className = 'caption-description placeholder'
32
+ this.dom.contentEditable = 'true'
33
+ this.contentDOM = this.dom
34
+ }
35
+ }
36
+
37
+ export default createNodeView(CaptionView)
@@ -0,0 +1,33 @@
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 { CaptionTitleNode } from '@manuscripts/transform'
18
+
19
+ import { BaseNodeView } from './base_node_view'
20
+ import { createNodeView } from './creators'
21
+
22
+ export class CaptionTitleView extends BaseNodeView<CaptionTitleNode> {
23
+ public initialise = () => {
24
+ this.createDOM()
25
+ }
26
+ protected createDOM() {
27
+ this.dom = document.createElement('label')
28
+ this.dom.className = 'caption-title placeholder'
29
+ this.dom.contentEditable = 'true'
30
+ this.contentDOM = this.dom
31
+ }
32
+ }
33
+ export default createNodeView(CaptionTitleView)
@@ -0,0 +1,67 @@
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 { CitationNode, ManuscriptNodeView } from '@manuscripts/transform'
18
+
19
+ import { sanitize } from '../lib/dompurify'
20
+ import { getBibliographyPluginState } from '../plugins/bibliography'
21
+ import { Trackable } from '../types'
22
+ import { BaseNodeView } from './base_node_view'
23
+ import { createNodeView } from './creators'
24
+
25
+ export class CitationView
26
+ extends BaseNodeView<Trackable<CitationNode>>
27
+ implements ManuscriptNodeView
28
+ {
29
+ public ignoreMutation = () => true
30
+
31
+ public initialise() {
32
+ this.createDOM()
33
+ this.updateContents()
34
+ }
35
+
36
+ public createDOM() {
37
+ this.dom = document.createElement('span')
38
+ this.dom.classList.add('citation')
39
+ this.dom.tabIndex = 0
40
+ }
41
+
42
+ public updateContents() {
43
+ super.updateContents()
44
+ const bib = getBibliographyPluginState(this.view.state)
45
+
46
+ if (!bib) {
47
+ return
48
+ }
49
+
50
+ const id = this.node.attrs.id
51
+ const text = bib.renderedCitations.get(id)
52
+ const fragment = sanitize(
53
+ text === '(n.d.)'
54
+ ? 'Missing citation data'
55
+ : text && text !== '[NO_PRINTED_FORM]'
56
+ ? text
57
+ : ' ',
58
+ {
59
+ ALLOWED_TAGS: ['i', 'b', 'span', 'sup', 'sub', '#text'],
60
+ }
61
+ )
62
+ this.dom.innerHTML = ''
63
+ this.dom.appendChild(fragment)
64
+ }
65
+ }
66
+
67
+ export default createNodeView(CitationView)