@manuscripts/body-editor 3.12.67 → 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.
- package/dist/cjs/components/toolbar/type-selector/styles.js +2 -1
- package/dist/cjs/versions.js +1 -1
- package/dist/es/components/toolbar/type-selector/styles.js +2 -1
- package/dist/es/versions.js +1 -1
- package/dist/types/components/toolbar/type-selector/styles.d.ts +2 -2
- package/dist/types/lib/footnotes.d.ts +4 -2
- package/dist/types/lib/utils.d.ts +5 -4
- package/dist/types/versions.d.ts +1 -1
- package/package.json +37 -36
- package/{dist/es/lib/statistics.js → src/__mocks__/styleMock.ts} +2 -14
- package/src/assets.ts +20 -0
- package/src/classes/collabProvider.ts +38 -0
- package/src/clipboard.ts +54 -0
- package/src/commands.ts +2109 -0
- package/src/components/ChangeHandlingForm.tsx +54 -0
- package/src/components/LanguageDropdown/index.tsx +343 -0
- package/src/components/affiliations/AffiliationForm.tsx +238 -0
- package/src/components/affiliations/AffiliationItem.tsx +151 -0
- package/src/components/affiliations/AffiliationList.tsx +71 -0
- package/src/components/affiliations/AffiliationsModal.tsx +676 -0
- package/src/components/affiliations/AffiliationsPanel.tsx +76 -0
- package/src/components/affiliations/CreateAffiliationModal.tsx +135 -0
- package/src/components/authors/AuthorDetailsForm.tsx +438 -0
- package/src/components/authors/AuthorList.tsx +81 -0
- package/src/components/authors/AuthorsModal.tsx +642 -0
- package/src/components/authors/AuthorsPanel.tsx +69 -0
- package/src/components/authors/CreateAuthorModal.tsx +172 -0
- package/src/components/authors/CreditDrawer.tsx +71 -0
- package/src/components/authors/DraggableAuthor.tsx +228 -0
- package/src/components/authors/useManageAffiliations.tsx +77 -0
- package/src/components/authors/useManageCredit.tsx +63 -0
- package/src/components/authors-affiliations/AuthorsAndAffiliationsModals.tsx +170 -0
- package/src/components/authors-affiliations/GenericPanel.tsx +164 -0
- package/src/components/authors-affiliations/ModalTabs.tsx +100 -0
- package/src/components/awards/AwardForm.tsx +338 -0
- package/src/components/awards/AwardModal.tsx +120 -0
- package/src/components/awards/DeleteAwardDiaolog.tsx +52 -0
- package/src/components/dialog/ConfirmationDialog.tsx +131 -0
- package/src/components/form/CreateModalStyles.tsx +37 -0
- package/src/components/form/FormFooter.tsx +54 -0
- package/src/components/form/FormPlaceholder.tsx +71 -0
- package/src/components/form/ModalFormActions.tsx +88 -0
- package/src/components/form/UnsavedLabel.tsx +49 -0
- package/src/components/hooks/use-debounce.ts +56 -0
- package/src/components/hooks/useAffiliationShowsErrorIndicator.ts +51 -0
- package/src/components/hooks/useAuthorShowsErrorIndicator.ts +73 -0
- package/src/components/keyboard-shortcuts-modal/FormattedShortcut.tsx +56 -0
- package/src/components/keyboard-shortcuts-modal/KeyboardShortcutsModal.tsx +283 -0
- package/src/components/keyboard-shortcuts-modal/keyboard-shortcuts.ts +304 -0
- package/src/components/keywords/AddKeywordInline.tsx +284 -0
- package/src/components/keywords/DeleteKeywordDialog.tsx +52 -0
- package/src/components/modal-drawer/GenericDrawer.tsx +65 -0
- package/src/components/modal-drawer/GenericDrawerGroup.tsx +125 -0
- package/src/components/outline/DraggableTree.tsx +438 -0
- package/src/components/outline/ManuscriptOutline.tsx +127 -0
- package/src/components/outline/Outline.tsx +141 -0
- package/src/components/references/BibliographyItemSource.ts +80 -0
- package/src/components/references/CitationEditor.tsx +301 -0
- package/src/components/references/CitationViewer.tsx +62 -0
- package/src/components/references/ImportBibliographyForm.tsx +232 -0
- package/src/components/references/ImportBibliographyModal.tsx +159 -0
- package/src/components/references/ReferenceForm/PersonDropDown.tsx +93 -0
- package/src/components/references/ReferenceForm/ReferenceForm.tsx +701 -0
- package/src/components/references/ReferenceForm/config.ts +133 -0
- package/src/components/references/ReferenceForm/styled-components.ts +156 -0
- package/src/components/references/ReferenceLine.tsx +43 -0
- package/src/components/references/ReferenceSearch.tsx +163 -0
- package/src/components/references/ReferenceSearchResults.tsx +113 -0
- package/src/components/references/ReferenceSearchResultsPlaceholder.tsx +71 -0
- package/src/components/references/ReferenceSearchSection.tsx +124 -0
- package/src/components/references/ReferencesEditor.tsx +61 -0
- package/src/components/references/ReferencesModal.tsx +352 -0
- package/src/components/references/SearchInput.tsx +98 -0
- package/src/components/toolbar/InsertEmbedDialog.tsx +222 -0
- package/src/components/toolbar/InsertTableDialog.tsx +208 -0
- package/src/components/toolbar/ListMenuItem.tsx +203 -0
- package/src/components/toolbar/helpers.ts +547 -0
- package/src/components/toolbar/type-selector/OptionComponent.tsx +89 -0
- package/src/components/toolbar/type-selector/TypeSelector.tsx +157 -0
- package/src/components/toolbar/type-selector/styles.ts +79 -0
- package/src/components/views/CrossReferenceItems.tsx +199 -0
- package/src/components/views/DeleteEmbedDialog.tsx +83 -0
- package/src/components/views/DeleteFootnoteDialog.tsx +54 -0
- package/src/components/views/FigureDropdown.tsx +423 -0
- package/src/components/views/FootnotesSelector.tsx +255 -0
- package/src/components/views/InsertSpecialCharacter.tsx +245 -0
- package/src/components/views/LinkForm.tsx +220 -0
- package/src/components/views/TableCellContextMenu.tsx +241 -0
- package/src/configs/ManuscriptsEditor.ts +140 -0
- package/src/configs/editor-plugins.ts +119 -0
- package/src/configs/editor-views.ts +139 -0
- package/src/icons.ts +62 -0
- package/src/index.ts +65 -0
- package/src/keys/highlight.ts +65 -0
- package/src/keys/index.ts +33 -0
- package/src/keys/keyword.ts +69 -0
- package/src/keys/list.ts +156 -0
- package/src/keys/misc.ts +112 -0
- package/src/keys/title.ts +221 -0
- package/src/lib/__tests__/__fixtures__/doc.json +388 -0
- package/src/lib/__tests__/__snapshots__/paste.test.ts.snap +24 -0
- package/src/lib/__tests__/authors.test.ts +202 -0
- package/src/lib/__tests__/helpers.test.ts +46 -0
- package/src/lib/__tests__/paste.test.ts +57 -0
- package/src/lib/__tests__/plugins.test.ts +176 -0
- package/src/lib/__tests__/url.test.ts +31 -0
- package/src/lib/array-reducer.ts +68 -0
- package/src/lib/authors-and-affiliations.ts +81 -0
- package/src/lib/authors.ts +67 -0
- package/src/lib/capabilities.ts +55 -0
- package/src/lib/codemirror.ts +37 -0
- package/src/lib/comments.ts +123 -0
- package/src/lib/context-menu.ts +745 -0
- package/src/lib/copy.ts +30 -0
- package/src/lib/crossref.ts +90 -0
- package/src/lib/dnd.ts +29 -0
- package/src/lib/doc.ts +167 -0
- package/src/lib/dompurify.ts +28 -0
- package/src/lib/files.ts +180 -0
- package/src/lib/footnotes.ts +83 -0
- package/src/lib/get-media-type.ts +105 -0
- package/src/lib/helpers.ts +199 -0
- package/src/lib/hierarchy.ts +117 -0
- package/src/lib/languages.ts +37 -0
- package/src/lib/lists.ts +56 -0
- package/src/lib/math.ts +111 -0
- package/src/lib/media.ts +334 -0
- package/src/lib/navigation-utils.ts +235 -0
- package/src/lib/normalize.ts +70 -0
- package/src/lib/paste.ts +304 -0
- package/src/lib/placeholder.ts +32 -0
- package/src/lib/platform.ts +18 -0
- package/src/lib/plugins.ts +22 -0
- package/src/lib/popper.ts +180 -0
- package/src/lib/position-menu.ts +184 -0
- package/src/lib/references.ts +94 -0
- package/src/lib/template.ts +29 -0
- package/src/lib/track-changes-utils.ts +34 -0
- package/{dist/types/lib/statistics.d.ts → src/lib/url.ts} +11 -8
- package/src/lib/use-do-with-debounce.ts +39 -0
- package/src/lib/utils.ts +323 -0
- package/src/lib/view.ts +100 -0
- package/src/menus.tsx +684 -0
- package/src/node-type-icons.tsx +83 -0
- package/src/plugins/__tests__/__fixtures__/deleted-footnote.json +140 -0
- package/src/plugins/__tests__/__fixtures__/inserted-footnote.json +153 -0
- package/src/plugins/__tests__/footnotes.test.ts +67 -0
- package/src/plugins/accessibility_element.ts +219 -0
- package/src/plugins/add-subtitle.ts +102 -0
- package/src/plugins/affiliations.ts +136 -0
- package/src/plugins/alt-titles.ts +219 -0
- package/src/plugins/bibliography.ts +235 -0
- package/src/plugins/comments.ts +328 -0
- package/src/plugins/cross-references.ts +70 -0
- package/src/plugins/detect-inconsistency/detect-inconsistency-utils.ts +102 -0
- package/src/plugins/detect-inconsistency/index.ts +55 -0
- package/src/plugins/detect-inconsistency/validators.ts +283 -0
- package/src/plugins/doi.ts +66 -0
- package/src/plugins/editor-props.ts +39 -0
- package/src/plugins/elements.ts +60 -0
- package/src/plugins/footnotes.ts +298 -0
- package/src/plugins/link.ts +53 -0
- package/src/plugins/lock-body.ts +136 -0
- package/src/plugins/move-node.ts +55 -0
- package/src/plugins/objects.ts +125 -0
- package/src/plugins/paragraphs.ts +90 -0
- package/src/plugins/persist.ts +64 -0
- package/src/plugins/persistent-cursor.ts +66 -0
- package/src/plugins/placeholder.ts +219 -0
- package/src/plugins/prevent-empty.ts +50 -0
- package/src/plugins/search-replace/index.ts +157 -0
- package/src/plugins/search-replace/lib.ts +95 -0
- package/src/plugins/section_category.ts +212 -0
- package/src/plugins/section_title/autocompletion.ts +87 -0
- package/src/plugins/section_title/index.ts +105 -0
- package/src/plugins/selected-suggestion.ts +243 -0
- package/src/plugins/tables-cursor-fix.ts +143 -0
- package/src/plugins/translations.ts +263 -0
- package/src/rules.ts +60 -0
- package/src/selection.ts +112 -0
- package/src/testing/default-capabilities.ts +48 -0
- package/src/testing/default-editor-data.ts +73 -0
- package/src/testing/empty-editor-doc.json +62 -0
- package/src/testing/polyfill-dom.ts +43 -0
- package/src/testing/section-categories.json +161 -0
- package/src/testing/setup-editor.ts +55 -0
- package/src/tests.ts +42 -0
- package/src/toolbar.tsx +259 -0
- package/src/types/@citation-js/core.d.ts +16 -0
- package/src/types/@citation-js/index.d.ts +16 -0
- package/src/types/@citation-js/plugin-bibtex.d.ts +16 -0
- package/src/types/@citation-js/plugin-csl.d.ts +16 -0
- package/src/types/@citation-js/plugin-doi.d.ts +16 -0
- package/src/types/@citation-js/plugin-enw.d.ts +16 -0
- package/src/types/@citation-js/plugin-pubmed.d.ts +16 -0
- package/src/types/@citation-js/plugin-ris.d.ts +16 -0
- package/src/types/citeproc.d.ts +124 -0
- package/src/types/css.d.ts +16 -0
- package/src/types/json.d.ts +17 -0
- package/src/types/prosemirror-dev-tools.d.ts +16 -0
- package/src/types/prosemirror-dropcursor.d.ts +16 -0
- package/src/types/styled-components.d.ts +23 -0
- package/src/types.ts +49 -0
- package/src/useEditor.ts +244 -0
- package/src/versions.ts +3 -0
- package/src/views/ReactSubView.tsx +145 -0
- package/src/views/abstracts.ts +46 -0
- package/src/views/accessibility_element.ts +86 -0
- package/src/views/affiliations.ts +254 -0
- package/src/views/alt_title.ts +85 -0
- package/src/views/alt_titles_section.ts +97 -0
- package/src/views/attachment.ts +160 -0
- package/src/views/attachments.ts +72 -0
- package/src/views/author_notes.ts +96 -0
- package/src/views/award.ts +194 -0
- package/src/views/awards.ts +59 -0
- package/src/views/base_node_view.ts +85 -0
- package/src/views/bibliography_element.ts +313 -0
- package/src/views/block_view.ts +100 -0
- package/src/views/blockquote_element.ts +26 -0
- package/src/views/blockquote_element_editable.ts +24 -0
- package/src/views/box_element.ts +33 -0
- package/src/views/caption.ts +37 -0
- package/src/views/caption_title.ts +33 -0
- package/src/views/citation.ts +67 -0
- package/src/views/citation_editable.ts +312 -0
- package/src/views/contributors.ts +341 -0
- package/src/views/creators.ts +82 -0
- package/src/views/cross_reference.ts +74 -0
- package/src/views/cross_reference_editable.ts +113 -0
- package/src/views/editable_block.ts +141 -0
- package/src/views/embed.ts +345 -0
- package/src/views/empty.ts +26 -0
- package/src/views/equation.ts +47 -0
- package/src/views/equation_editable.ts +84 -0
- package/src/views/equation_element.ts +29 -0
- package/src/views/equation_element_editable.ts +21 -0
- package/src/views/figure.ts +84 -0
- package/src/views/figure_editable.ts +361 -0
- package/src/views/figure_element.ts +197 -0
- package/src/views/figure_element_editable.ts +21 -0
- package/src/views/footnote.ts +236 -0
- package/src/views/footnotes_element.ts +54 -0
- package/src/views/general_table_footnote.ts +140 -0
- package/src/views/hero_image.ts +76 -0
- package/src/views/hero_image_editable.ts +21 -0
- package/src/views/image_element.ts +373 -0
- package/src/views/image_element_editable.ts +21 -0
- package/src/views/inline_equation.ts +47 -0
- package/src/views/inline_equation_editable.ts +70 -0
- package/src/views/inline_footnote.ts +264 -0
- package/src/views/inline_footnote_editable.ts +20 -0
- package/src/views/keyword.ts +127 -0
- package/src/views/keyword_group.ts +109 -0
- package/src/views/link.ts +27 -0
- package/src/views/link_editable.ts +169 -0
- package/src/views/list.ts +46 -0
- package/src/views/list_item.ts +26 -0
- package/src/views/paragraph.ts +26 -0
- package/src/views/paragraph_editable.ts +21 -0
- package/src/views/placeholder.ts +35 -0
- package/src/views/placeholder_element.ts +38 -0
- package/src/views/placeholder_element_editable.ts +21 -0
- package/src/views/pullquote_element.ts +106 -0
- package/src/views/pullquote_element_editable.ts +24 -0
- package/src/views/quote_image_editable.ts +84 -0
- package/src/views/section.ts +64 -0
- package/src/views/section_label.ts +20 -0
- package/src/views/section_title.ts +87 -0
- package/src/views/section_title_editable.ts +21 -0
- package/src/views/subtitle.ts +42 -0
- package/src/views/subtitle_editable.ts +20 -0
- package/src/views/subtitles.ts +34 -0
- package/src/views/subtitles_editable.ts +21 -0
- package/src/views/supplement.ts +236 -0
- package/src/views/supplement_editable.ts +20 -0
- package/src/views/supplements.ts +65 -0
- package/src/views/supplements_editable.ts +21 -0
- package/src/views/table_cell.ts +150 -0
- package/src/views/table_element.ts +33 -0
- package/src/views/table_element_editable.ts +21 -0
- package/src/views/table_element_footer.ts +41 -0
- package/src/views/title.ts +46 -0
- package/src/views/title_editable.ts +20 -0
- package/src/views/trans_graphical_abstract.ts +55 -0
- package/src/views/trans_graphical_abstract_editable.ts +21 -0
- package/src/views/translated_abstract.ts +53 -0
- package/src/views/translated_abstract_editable.ts +21 -0
- package/dist/cjs/lib/statistics.js +0 -38
|
@@ -0,0 +1,236 @@
|
|
|
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 { isDeleted, isPendingInsert } from '@manuscripts/track-changes-plugin'
|
|
19
|
+
import { FootnoteNode, ManuscriptNode, schema } from '@manuscripts/transform'
|
|
20
|
+
|
|
21
|
+
import { isEqual } from 'lodash'
|
|
22
|
+
import { NodeSelection, Transaction } from 'prosemirror-state'
|
|
23
|
+
import { findParentNodeOfTypeClosestToPos } from 'prosemirror-utils'
|
|
24
|
+
|
|
25
|
+
import {
|
|
26
|
+
DeleteFootnoteDialog,
|
|
27
|
+
DeleteFootnoteDialogProps,
|
|
28
|
+
} from '../components/views/DeleteFootnoteDialog'
|
|
29
|
+
import { alertIcon } from '../icons'
|
|
30
|
+
import { getFootnotesElementState } from '../lib/footnotes'
|
|
31
|
+
import { Trackable } from '../types'
|
|
32
|
+
import { BaseNodeView } from './base_node_view'
|
|
33
|
+
import { createNodeView } from './creators'
|
|
34
|
+
import ReactSubView from './ReactSubView'
|
|
35
|
+
import { handleEnterKey } from '../lib/navigation-utils'
|
|
36
|
+
|
|
37
|
+
export class FootnoteView extends BaseNodeView<Trackable<FootnoteNode>> {
|
|
38
|
+
dialog: HTMLElement
|
|
39
|
+
contextMenu: HTMLDivElement
|
|
40
|
+
|
|
41
|
+
public initialise = () => {
|
|
42
|
+
this.dom = document.createElement('div')
|
|
43
|
+
this.dom.classList.add('footnote')
|
|
44
|
+
this.dom.tabIndex = 0
|
|
45
|
+
this.contentDOM = document.createElement('div')
|
|
46
|
+
this.contentDOM.classList.add('footnote-text')
|
|
47
|
+
this.dom.addEventListener('mousedown', (e) => this.handleClick(e, false))
|
|
48
|
+
this.dom.addEventListener(
|
|
49
|
+
'keydown',
|
|
50
|
+
handleEnterKey((e) => this.handleClick(e, true))
|
|
51
|
+
)
|
|
52
|
+
this.updateContents()
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
public updateContents() {
|
|
56
|
+
super.updateContents()
|
|
57
|
+
|
|
58
|
+
const { id, fn } = this.getFootnoteState()
|
|
59
|
+
|
|
60
|
+
if (!fn) {
|
|
61
|
+
return
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const marker = document.createElement('span')
|
|
65
|
+
if (!isDeleted(this.node) && fn.unusedFootnoteIDs.has(id)) {
|
|
66
|
+
marker.classList.add('uncited-footnote')
|
|
67
|
+
marker.innerHTML = alertIcon
|
|
68
|
+
} else {
|
|
69
|
+
marker.classList.add('footnote-marker')
|
|
70
|
+
marker.innerText = fn.labels.get(id) || ''
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
this.dom.innerHTML = ''
|
|
74
|
+
this.dom.appendChild(marker)
|
|
75
|
+
this.contentDOM && this.dom.appendChild(this.contentDOM)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
getFootnoteState() {
|
|
79
|
+
const id = this.node.attrs.id
|
|
80
|
+
const fn = getFootnotesElementState(this.view.state, id)
|
|
81
|
+
return { id, fn }
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
showContextMenu(element: HTMLElement, autoFocus: boolean) {
|
|
85
|
+
this.props.popper.destroy()
|
|
86
|
+
|
|
87
|
+
const can = this.props.getCapabilities()
|
|
88
|
+
const { id, fn } = this.getFootnoteState()
|
|
89
|
+
|
|
90
|
+
const componentProps: ContextMenuProps = {
|
|
91
|
+
actions: [],
|
|
92
|
+
}
|
|
93
|
+
if (!fn?.unusedFootnoteIDs.has(id)) {
|
|
94
|
+
componentProps.actions.push({
|
|
95
|
+
label: 'Go to footnote Refernce',
|
|
96
|
+
action: () => this.handleMarkerClick(),
|
|
97
|
+
icon: 'Scroll',
|
|
98
|
+
})
|
|
99
|
+
}
|
|
100
|
+
if (can.editArticle && !isDeleted(this.node)) {
|
|
101
|
+
componentProps.actions.push({
|
|
102
|
+
label: 'Delete',
|
|
103
|
+
action: () => this.handleDeleteClick(),
|
|
104
|
+
icon: 'Delete',
|
|
105
|
+
})
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
this.contextMenu = ReactSubView(
|
|
109
|
+
this.props,
|
|
110
|
+
ContextMenu,
|
|
111
|
+
componentProps,
|
|
112
|
+
this.node,
|
|
113
|
+
this.getPos,
|
|
114
|
+
this.view,
|
|
115
|
+
['context-menu', 'footnote-context-menu']
|
|
116
|
+
)
|
|
117
|
+
this.props.popper.show(
|
|
118
|
+
element,
|
|
119
|
+
this.contextMenu,
|
|
120
|
+
'right-start',
|
|
121
|
+
true,
|
|
122
|
+
[],
|
|
123
|
+
autoFocus
|
|
124
|
+
)
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
handleClick = (event: Event, fromKeyboard = false) => {
|
|
128
|
+
const element = event.target as HTMLElement
|
|
129
|
+
const item = element.closest('.footnote')
|
|
130
|
+
if (item) {
|
|
131
|
+
this.showContextMenu(item as HTMLElement, fromKeyboard)
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
handleMarkerClick = (e?: Event) => {
|
|
136
|
+
e?.preventDefault()
|
|
137
|
+
e?.stopPropagation()
|
|
138
|
+
|
|
139
|
+
const id = this.node.attrs.id
|
|
140
|
+
const fn = getFootnotesElementState(this.view.state, id)
|
|
141
|
+
|
|
142
|
+
if (!fn) {
|
|
143
|
+
return
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
for (const [node, pos] of fn.inlineFootnotes) {
|
|
147
|
+
if (node.attrs.rids.includes(id)) {
|
|
148
|
+
const tr = this.view.state.tr
|
|
149
|
+
const selection = NodeSelection.create(this.view.state.doc, pos)
|
|
150
|
+
tr.setSelection(selection)
|
|
151
|
+
tr.scrollIntoView()
|
|
152
|
+
this.view.dispatch(tr)
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
handleDeleteClick = (e?: Event) => {
|
|
158
|
+
e?.preventDefault()
|
|
159
|
+
e?.stopPropagation()
|
|
160
|
+
const componentProps: DeleteFootnoteDialogProps = {
|
|
161
|
+
header: 'Delete footnote',
|
|
162
|
+
message:
|
|
163
|
+
'This action will entirely remove the footnote from the list because it will no longer be used.',
|
|
164
|
+
handleDelete: this.handleDelete,
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
this.dialog = ReactSubView(
|
|
168
|
+
this.props,
|
|
169
|
+
DeleteFootnoteDialog,
|
|
170
|
+
componentProps,
|
|
171
|
+
this.node,
|
|
172
|
+
this.getPos,
|
|
173
|
+
this.view
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
this.props.popper.show(this.dom, this.dialog, 'auto', false)
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
handleDelete = () => {
|
|
180
|
+
const tr = this.view.state.tr
|
|
181
|
+
this.deleteInlineFootnotes(tr)
|
|
182
|
+
this.deleteFootnote(tr)
|
|
183
|
+
this.view.dispatch(tr)
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
deleteInlineFootnotes = (tr: Transaction) => {
|
|
187
|
+
const id = this.node.attrs.id
|
|
188
|
+
const fns = getFootnotesElementState(this.view.state, this.node.attrs.id)
|
|
189
|
+
fns?.inlineFootnotes.forEach(([node, pos]) => {
|
|
190
|
+
pos = tr.mapping.map(pos)
|
|
191
|
+
const rids = node.attrs.rids.filter((rid) => rid !== id)
|
|
192
|
+
if (isEqual(rids, node.attrs.rids)) {
|
|
193
|
+
return
|
|
194
|
+
}
|
|
195
|
+
if (!rids.length) {
|
|
196
|
+
tr.delete(pos, pos + node.nodeSize)
|
|
197
|
+
} else {
|
|
198
|
+
tr.setNodeAttribute(pos, 'rids', rids)
|
|
199
|
+
}
|
|
200
|
+
})
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
deleteFootnote = (tr: Transaction) => {
|
|
204
|
+
const pos = tr.mapping.map(this.getPos())
|
|
205
|
+
const $pos = tr.doc.resolve(pos)
|
|
206
|
+
const element = findParentNodeOfTypeClosestToPos(
|
|
207
|
+
$pos,
|
|
208
|
+
schema.nodes.footnotes_element
|
|
209
|
+
)
|
|
210
|
+
tr.delete(pos, pos + this.node.nodeSize)
|
|
211
|
+
|
|
212
|
+
if (
|
|
213
|
+
element &&
|
|
214
|
+
getEffectiveChildCount(element.node) <= 1 &&
|
|
215
|
+
!isPendingInsert(this.node)
|
|
216
|
+
) {
|
|
217
|
+
tr.delete(
|
|
218
|
+
tr.mapping.map(element.pos),
|
|
219
|
+
tr.mapping.map(element.pos + element.node.nodeSize)
|
|
220
|
+
)
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
const getEffectiveChildCount = (node: ManuscriptNode) => {
|
|
226
|
+
let count = 0
|
|
227
|
+
for (let i = 0; i < node.childCount; i++) {
|
|
228
|
+
const child = node.child(i)
|
|
229
|
+
if (!isDeleted(child)) {
|
|
230
|
+
count++
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
return count
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
export default createNodeView(FootnoteView)
|
|
@@ -0,0 +1,54 @@
|
|
|
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 { FootnotesElementNode, ManuscriptNode } from '@manuscripts/transform'
|
|
18
|
+
|
|
19
|
+
import BlockView from './block_view'
|
|
20
|
+
import { createNodeOrElementView } from './creators'
|
|
21
|
+
|
|
22
|
+
export class FootnotesElementView extends BlockView<FootnotesElementNode> {
|
|
23
|
+
public elementType = 'div'
|
|
24
|
+
|
|
25
|
+
updateClasses() {
|
|
26
|
+
super.updateClasses()
|
|
27
|
+
updateClasses(this.node, this.dom)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
updateContents() {
|
|
31
|
+
super.updateContents()
|
|
32
|
+
this.checkEditability()
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
checkEditability = () => {
|
|
36
|
+
const editable =
|
|
37
|
+
this.props.getCapabilities().editArticle && this.node.childCount
|
|
38
|
+
? 'true'
|
|
39
|
+
: 'false'
|
|
40
|
+
this.contentDOM?.setAttribute('contenteditable', editable)
|
|
41
|
+
this.dom?.setAttribute('contenteditable', editable)
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const updateClasses = (node: ManuscriptNode, dom: HTMLElement) => {
|
|
46
|
+
!node.childCount && dom.classList.add('empty-node')
|
|
47
|
+
dom.classList.add('footnotes-element')
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export default createNodeOrElementView(
|
|
51
|
+
FootnotesElementView,
|
|
52
|
+
'div',
|
|
53
|
+
updateClasses
|
|
54
|
+
)
|
|
@@ -0,0 +1,140 @@
|
|
|
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 { GeneralTableFootnoteNode, schema } from '@manuscripts/transform'
|
|
19
|
+
import {
|
|
20
|
+
findChildrenByType,
|
|
21
|
+
findParentNodeOfTypeClosestToPos,
|
|
22
|
+
} from 'prosemirror-utils'
|
|
23
|
+
|
|
24
|
+
import {
|
|
25
|
+
DeleteFootnoteDialog,
|
|
26
|
+
DeleteFootnoteDialogProps,
|
|
27
|
+
} from '../components/views/DeleteFootnoteDialog'
|
|
28
|
+
import { Trackable } from '../types'
|
|
29
|
+
import { BaseNodeView } from './base_node_view'
|
|
30
|
+
import { createNodeView } from './creators'
|
|
31
|
+
import ReactSubView from './ReactSubView'
|
|
32
|
+
import { isDeleted, isPendingInsert } from '@manuscripts/track-changes-plugin'
|
|
33
|
+
|
|
34
|
+
export class GeneralTableFootnoteView extends BaseNodeView<
|
|
35
|
+
Trackable<GeneralTableFootnoteNode>
|
|
36
|
+
> {
|
|
37
|
+
dialog: HTMLElement
|
|
38
|
+
contextMenu: HTMLDivElement
|
|
39
|
+
|
|
40
|
+
public initialise = () => {
|
|
41
|
+
this.dom = document.createElement('div')
|
|
42
|
+
this.dom.classList.add('footnote', 'general-table-footnote')
|
|
43
|
+
this.dom.addEventListener('mousedown', this.handleClick)
|
|
44
|
+
this.contentDOM = document.createElement('div')
|
|
45
|
+
this.contentDOM.classList.add('footnote-text')
|
|
46
|
+
this.updateContents()
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
public updateContents() {
|
|
50
|
+
super.updateContents()
|
|
51
|
+
this.dom.innerHTML = ''
|
|
52
|
+
this.contentDOM && this.dom.appendChild(this.contentDOM)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
handleClick = (e: Event) => {
|
|
56
|
+
const element = e.target as HTMLElement
|
|
57
|
+
const can = this.props.getCapabilities()
|
|
58
|
+
|
|
59
|
+
if (can.editArticle) {
|
|
60
|
+
const item = element.closest('.general-table-footnote')
|
|
61
|
+
if (item) {
|
|
62
|
+
this.showContextMenu(item as HTMLElement)
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
showContextMenu(element: HTMLElement) {
|
|
68
|
+
this.props.popper.destroy()
|
|
69
|
+
|
|
70
|
+
const componentProps: ContextMenuProps = {
|
|
71
|
+
actions: [],
|
|
72
|
+
}
|
|
73
|
+
if (!isDeleted(this.node)) {
|
|
74
|
+
componentProps.actions.push({
|
|
75
|
+
label: 'Delete',
|
|
76
|
+
action: () => this.handleDeleteClick(),
|
|
77
|
+
icon: 'Delete',
|
|
78
|
+
})
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
this.contextMenu = ReactSubView(
|
|
82
|
+
this.props,
|
|
83
|
+
ContextMenu,
|
|
84
|
+
componentProps,
|
|
85
|
+
this.node,
|
|
86
|
+
this.getPos,
|
|
87
|
+
this.view,
|
|
88
|
+
['context-menu', 'footnote-context-menu']
|
|
89
|
+
)
|
|
90
|
+
this.props.popper.show(element, this.contextMenu, 'right-start')
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
handleDeleteClick = () => {
|
|
94
|
+
const componentProps: DeleteFootnoteDialogProps = {
|
|
95
|
+
header: 'Delete table general note',
|
|
96
|
+
message: 'This action will entirely remove the table general note.',
|
|
97
|
+
handleDelete: this.handleDelete,
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
this.dialog = ReactSubView(
|
|
101
|
+
this.props,
|
|
102
|
+
DeleteFootnoteDialog,
|
|
103
|
+
componentProps,
|
|
104
|
+
this.node,
|
|
105
|
+
this.getPos,
|
|
106
|
+
this.view
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
this.props.popper.show(this.dom, this.dialog, 'auto', false)
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
handleDelete = () => {
|
|
113
|
+
const tr = this.view.state.tr
|
|
114
|
+
|
|
115
|
+
const pos = this.getPos()
|
|
116
|
+
const $pos = this.view.state.doc.resolve(pos)
|
|
117
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
118
|
+
const footer = findParentNodeOfTypeClosestToPos(
|
|
119
|
+
$pos,
|
|
120
|
+
schema.nodes.table_element_footer
|
|
121
|
+
)!
|
|
122
|
+
const element = findChildrenByType(
|
|
123
|
+
footer.node,
|
|
124
|
+
schema.nodes.general_table_footnote
|
|
125
|
+
)[0]
|
|
126
|
+
if (element && !isDeleted(element.node)) {
|
|
127
|
+
const from = tr.mapping.map(pos)
|
|
128
|
+
const to = tr.mapping.map(from + this.node.nodeSize)
|
|
129
|
+
tr.delete(from, to)
|
|
130
|
+
}
|
|
131
|
+
if (footer.node.childCount <= 1 && !isPendingInsert(element.node)) {
|
|
132
|
+
const from = tr.mapping.map(footer.pos)
|
|
133
|
+
const to = tr.mapping.map(from + footer.node.nodeSize)
|
|
134
|
+
tr.delete(from, to)
|
|
135
|
+
}
|
|
136
|
+
this.view.dispatch(tr)
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export default createNodeView(GeneralTableFootnoteView)
|
|
@@ -0,0 +1,76 @@
|
|
|
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 { FigureElementNode } from '@manuscripts/transform'
|
|
18
|
+
|
|
19
|
+
import { arrowUp } from '../icons'
|
|
20
|
+
import { handleEnterKey } from '../lib/navigation-utils'
|
|
21
|
+
import { Trackable } from '../types'
|
|
22
|
+
import BlockView from './block_view'
|
|
23
|
+
import { createNodeView } from './creators'
|
|
24
|
+
|
|
25
|
+
export class HeroImageView extends BlockView<Trackable<FigureElementNode>> {
|
|
26
|
+
private container: HTMLElement
|
|
27
|
+
private collapsed = false
|
|
28
|
+
|
|
29
|
+
public ignoreMutation = () => true
|
|
30
|
+
|
|
31
|
+
public createElement = () => {
|
|
32
|
+
this.container = document.createElement('div')
|
|
33
|
+
this.container.classList.add('block', 'hero-image-container')
|
|
34
|
+
this.dom.appendChild(this.container)
|
|
35
|
+
|
|
36
|
+
this.container.appendChild(this.createPanel())
|
|
37
|
+
|
|
38
|
+
this.contentDOM = document.createElement('figure')
|
|
39
|
+
this.contentDOM.classList.add('figure-block', 'hero-image-figure')
|
|
40
|
+
this.contentDOM.setAttribute('id', this.node.attrs.id)
|
|
41
|
+
|
|
42
|
+
this.container.appendChild(this.contentDOM)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
createPanel() {
|
|
46
|
+
const panel = document.createElement('div')
|
|
47
|
+
panel.classList.add('panel-header')
|
|
48
|
+
|
|
49
|
+
const label = document.createElement('span')
|
|
50
|
+
label.textContent = 'Hero image'
|
|
51
|
+
label.contentEditable = 'false'
|
|
52
|
+
|
|
53
|
+
const heroImageToggleBtn = document.createElement('button')
|
|
54
|
+
heroImageToggleBtn.classList.add('toggle-btn', 'button-reset')
|
|
55
|
+
|
|
56
|
+
heroImageToggleBtn.innerHTML = arrowUp
|
|
57
|
+
heroImageToggleBtn.classList.toggle('collapsed', this.collapsed)
|
|
58
|
+
|
|
59
|
+
const handleToggle = () => {
|
|
60
|
+
this.collapsed = !this.collapsed
|
|
61
|
+
if (this.contentDOM) {
|
|
62
|
+
this.contentDOM.style.display = this.collapsed ? 'none' : ''
|
|
63
|
+
}
|
|
64
|
+
heroImageToggleBtn.classList.toggle('collapsed', this.collapsed)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
heroImageToggleBtn.onclick = handleToggle
|
|
68
|
+
heroImageToggleBtn.addEventListener('keydown', handleEnterKey(handleToggle))
|
|
69
|
+
|
|
70
|
+
panel.appendChild(label)
|
|
71
|
+
panel.appendChild(heroImageToggleBtn)
|
|
72
|
+
return panel
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export default createNodeView(HeroImageView)
|
|
@@ -0,0 +1,21 @@
|
|
|
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 { createEditableNodeView } from './creators'
|
|
18
|
+
import { EditableBlock } from './editable_block'
|
|
19
|
+
import { HeroImageView } from './hero_image'
|
|
20
|
+
|
|
21
|
+
export default createEditableNodeView(EditableBlock(HeroImageView))
|