@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.
- 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
package/src/lib/utils.ts
ADDED
|
@@ -0,0 +1,323 @@
|
|
|
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
|
+
BibliographyItemAttrs,
|
|
19
|
+
BibliographyItemType,
|
|
20
|
+
isElementNodeType,
|
|
21
|
+
isSectionNodeType,
|
|
22
|
+
ManuscriptEditorState,
|
|
23
|
+
ManuscriptNode,
|
|
24
|
+
ManuscriptNodeType,
|
|
25
|
+
schema,
|
|
26
|
+
} from '@manuscripts/transform'
|
|
27
|
+
import {
|
|
28
|
+
Fragment,
|
|
29
|
+
Node as ProseMirrorNode,
|
|
30
|
+
NodeType,
|
|
31
|
+
ResolvedPos,
|
|
32
|
+
} from 'prosemirror-model'
|
|
33
|
+
import { EditorState, Selection } from 'prosemirror-state'
|
|
34
|
+
import {
|
|
35
|
+
ContentNodeWithPos,
|
|
36
|
+
findChildrenByType,
|
|
37
|
+
findParentNode,
|
|
38
|
+
findParentNodeOfTypeClosestToPos,
|
|
39
|
+
} from 'prosemirror-utils'
|
|
40
|
+
|
|
41
|
+
import { fieldConfigMap } from '../components/references/ReferenceForm/config'
|
|
42
|
+
import { arrowDown } from '../icons'
|
|
43
|
+
import { handleEnterKey } from './navigation-utils'
|
|
44
|
+
import { getEditorProps } from '../plugins/editor-props'
|
|
45
|
+
|
|
46
|
+
export function* iterateChildren(
|
|
47
|
+
node: ManuscriptNode,
|
|
48
|
+
recurse = false
|
|
49
|
+
): Iterable<ManuscriptNode> {
|
|
50
|
+
for (let i = 0; i < node.childCount; i++) {
|
|
51
|
+
const child = node.child(i)
|
|
52
|
+
yield child
|
|
53
|
+
|
|
54
|
+
if (recurse) {
|
|
55
|
+
for (const grandchild of iterateChildren(child, true)) {
|
|
56
|
+
yield grandchild
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export const getMatchingChild = (
|
|
63
|
+
parent: ManuscriptNode,
|
|
64
|
+
matcher: (node: ManuscriptNode) => boolean,
|
|
65
|
+
deep = false
|
|
66
|
+
): ManuscriptNode | undefined => {
|
|
67
|
+
for (const node of iterateChildren(parent, deep)) {
|
|
68
|
+
if (matcher(node)) {
|
|
69
|
+
return node
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export const getMatchingDescendant = (
|
|
75
|
+
parent: ManuscriptNode,
|
|
76
|
+
matcher: (node: ManuscriptNode) => boolean
|
|
77
|
+
): ManuscriptNode | undefined => {
|
|
78
|
+
for (const node of iterateChildren(parent, true)) {
|
|
79
|
+
if (matcher(node)) {
|
|
80
|
+
return node
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export const getChildOfType = (
|
|
86
|
+
parent: ManuscriptNode,
|
|
87
|
+
nodeType: ManuscriptNodeType,
|
|
88
|
+
deep = false
|
|
89
|
+
): boolean =>
|
|
90
|
+
!!getMatchingChild(parent, (node) => node.type.name === nodeType.name, deep)
|
|
91
|
+
|
|
92
|
+
export const findParentNodeWithId: (selection: Selection) => ContentNodeWithPos | undefined = findParentNode((node) => 'id' in node.attrs)
|
|
93
|
+
|
|
94
|
+
export const findParentNodeWithIdValue: (selection: Selection) => ContentNodeWithPos | undefined = findParentNode((node) => node.attrs.id)
|
|
95
|
+
|
|
96
|
+
export const findParentSection: (selection: Selection) => ContentNodeWithPos | undefined = findParentNode((node) =>
|
|
97
|
+
isSectionNodeType(node.type)
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
export const findParentElement = (selection: Selection, validIds?: string[]): ContentNodeWithPos | undefined =>
|
|
101
|
+
findParentNode((node) => {
|
|
102
|
+
// if validIds was passed and this element is not in it, then keep looking
|
|
103
|
+
if (validIds && !validIds.includes(node.attrs.id)) {
|
|
104
|
+
return false
|
|
105
|
+
}
|
|
106
|
+
return isElementNodeType(node.type) && node.attrs.id
|
|
107
|
+
})(selection)
|
|
108
|
+
|
|
109
|
+
export const isChildOfNodeTypes = (
|
|
110
|
+
doc: ManuscriptNode,
|
|
111
|
+
pos: number,
|
|
112
|
+
parentNodeTypes: NodeType[]
|
|
113
|
+
) => {
|
|
114
|
+
if (pos > doc.content.size) {
|
|
115
|
+
return false
|
|
116
|
+
}
|
|
117
|
+
const resolvedPos = doc.resolve(pos)
|
|
118
|
+
// Iterate through the parent nodes
|
|
119
|
+
for (let depth = resolvedPos.depth; depth >= 0; depth--) {
|
|
120
|
+
if (parentNodeTypes.includes(resolvedPos.node(depth).type)) {
|
|
121
|
+
return true
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return false
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export const isSelectionInNode = (
|
|
129
|
+
state: EditorState,
|
|
130
|
+
targetNode: ProseMirrorNode
|
|
131
|
+
) => {
|
|
132
|
+
const resolvedFrom = state.doc.resolve(state.selection.from)
|
|
133
|
+
|
|
134
|
+
for (let depth = resolvedFrom.depth; depth >= 0; depth--) {
|
|
135
|
+
const node = resolvedFrom.node(depth)
|
|
136
|
+
if (node === targetNode) {
|
|
137
|
+
return true
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
return false
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
export const isSelectionInBody = (state: EditorState): boolean => {
|
|
144
|
+
return isSelectionInNodeByType(state, 'body')
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const isSelectionInNodeByType = (
|
|
148
|
+
state: EditorState,
|
|
149
|
+
nodeType: string
|
|
150
|
+
): boolean => {
|
|
151
|
+
const { $from } = state.selection
|
|
152
|
+
|
|
153
|
+
for (let depth = $from.depth; depth >= 0; depth--) {
|
|
154
|
+
if ($from.node(depth).type.name === nodeType) {
|
|
155
|
+
return true
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
return false
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
export const createHeader = (typeName: string, text: string) => {
|
|
163
|
+
const header = document.createElement('h1')
|
|
164
|
+
header.classList.add(`title-${typeName}`, 'authors-info-header')
|
|
165
|
+
header.textContent = text
|
|
166
|
+
return header
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
export const isNotNull = <T>(a: T | null): a is T => a !== null
|
|
170
|
+
|
|
171
|
+
export const hasParent = (
|
|
172
|
+
$pos: ResolvedPos,
|
|
173
|
+
type: ManuscriptNodeType | ManuscriptNodeType[]
|
|
174
|
+
) => {
|
|
175
|
+
if (Array.isArray(type)) {
|
|
176
|
+
return type.some(
|
|
177
|
+
(nodeType) => !!findParentNodeOfTypeClosestToPos($pos, nodeType)
|
|
178
|
+
)
|
|
179
|
+
}
|
|
180
|
+
return !!findParentNodeOfTypeClosestToPos($pos, type)
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// It will check if the field should be rendered based on selected item type
|
|
184
|
+
// and field name
|
|
185
|
+
export const shouldRenderField = (
|
|
186
|
+
field: string,
|
|
187
|
+
type: BibliographyItemType
|
|
188
|
+
): boolean => {
|
|
189
|
+
return fieldConfigMap[type]?.has(field) ?? false
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// It will clean unnecessary fields from the item
|
|
193
|
+
// id and type will be kept
|
|
194
|
+
export const cleanItemValues = (item: BibliographyItemAttrs) => {
|
|
195
|
+
const type = item.type as BibliographyItemType
|
|
196
|
+
const cleanedItem: BibliographyItemAttrs = { ...item }
|
|
197
|
+
|
|
198
|
+
for (const key of Object.keys(item) as (keyof BibliographyItemAttrs)[]) {
|
|
199
|
+
if (!shouldRenderField(key, type)) {
|
|
200
|
+
switch (key) {
|
|
201
|
+
case 'id':
|
|
202
|
+
case 'type':
|
|
203
|
+
break
|
|
204
|
+
case 'author':
|
|
205
|
+
case 'editor':
|
|
206
|
+
case 'issued':
|
|
207
|
+
case 'accessed':
|
|
208
|
+
case 'event-date':
|
|
209
|
+
cleanedItem[key] = undefined
|
|
210
|
+
break
|
|
211
|
+
default:
|
|
212
|
+
cleanedItem[key] = ''
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
return cleanedItem
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
export const isBodyLocked = (state: EditorState) => {
|
|
220
|
+
const props = getEditorProps(state)
|
|
221
|
+
return (
|
|
222
|
+
!!findChildrenByType(state.doc, schema.nodes.attachment).length &&
|
|
223
|
+
props.lockBody
|
|
224
|
+
)
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// It checks if the selection is inside a body node and if the body is locked
|
|
228
|
+
// the body is locked if feature lockBody is set true and there is an attachment node in document
|
|
229
|
+
export const isEditAllowed = (state: EditorState) => {
|
|
230
|
+
return !(isBodyLocked(state) && isSelectionInBody(state))
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
export const createToggleButton = (
|
|
234
|
+
listener: (event: MouseEvent | KeyboardEvent) => void,
|
|
235
|
+
what: string
|
|
236
|
+
) => {
|
|
237
|
+
const altTitlesButton = document.createElement('button')
|
|
238
|
+
altTitlesButton.classList.add('toggle-button-open', 'button-reset')
|
|
239
|
+
altTitlesButton.setAttribute('aria-label', `Expand ${what}`)
|
|
240
|
+
altTitlesButton.innerHTML = arrowDown
|
|
241
|
+
const activate = (e: MouseEvent | KeyboardEvent) => {
|
|
242
|
+
e.preventDefault()
|
|
243
|
+
listener(e)
|
|
244
|
+
}
|
|
245
|
+
altTitlesButton.addEventListener('click', (e) => {
|
|
246
|
+
activate(e)
|
|
247
|
+
})
|
|
248
|
+
altTitlesButton.addEventListener('keydown', handleEnterKey(activate))
|
|
249
|
+
return altTitlesButton
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
export const getInsertPos = (
|
|
253
|
+
type: ManuscriptNodeType,
|
|
254
|
+
parent: ManuscriptNode,
|
|
255
|
+
pos: number
|
|
256
|
+
) => {
|
|
257
|
+
let insertPos = pos + parent.nodeSize - 1
|
|
258
|
+
|
|
259
|
+
parent.forEach((child, offset, index) => {
|
|
260
|
+
if (parent.canReplaceWith(index, index, type)) {
|
|
261
|
+
insertPos = pos + offset
|
|
262
|
+
}
|
|
263
|
+
})
|
|
264
|
+
|
|
265
|
+
return insertPos
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// this will look just at parent node children
|
|
269
|
+
export const findInsertionPosition = (
|
|
270
|
+
type: ManuscriptNodeType,
|
|
271
|
+
doc: ManuscriptNode
|
|
272
|
+
) => {
|
|
273
|
+
let insertPos = 0
|
|
274
|
+
|
|
275
|
+
doc.forEach((child, offset, index) => {
|
|
276
|
+
if (doc.canReplaceWith(index, index, type)) {
|
|
277
|
+
insertPos = offset
|
|
278
|
+
}
|
|
279
|
+
})
|
|
280
|
+
// this will test if we can insert target type as last child in parent node
|
|
281
|
+
if (
|
|
282
|
+
insertPos === 0 &&
|
|
283
|
+
doc.canReplaceWith(doc.childCount, doc.childCount, type)
|
|
284
|
+
) {
|
|
285
|
+
insertPos = doc.content.size
|
|
286
|
+
}
|
|
287
|
+
return insertPos
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
export const filterBlockNodes = (
|
|
291
|
+
fragment: Fragment,
|
|
292
|
+
predicate?: (node: ProseMirrorNode) => boolean
|
|
293
|
+
) => {
|
|
294
|
+
const updatedNodes: ProseMirrorNode[] = []
|
|
295
|
+
|
|
296
|
+
fragment.forEach((child) => {
|
|
297
|
+
if (!child.isBlock) {
|
|
298
|
+
updatedNodes.push(child)
|
|
299
|
+
return
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
const newContent = child.content.size
|
|
303
|
+
? filterBlockNodes(child.content, predicate)
|
|
304
|
+
: child.content
|
|
305
|
+
if (!predicate || predicate(child)) {
|
|
306
|
+
updatedNodes.push(child.type.create(child.attrs, newContent, child.marks))
|
|
307
|
+
}
|
|
308
|
+
})
|
|
309
|
+
|
|
310
|
+
return Fragment.fromArray(updatedNodes)
|
|
311
|
+
}
|
|
312
|
+
export const getLastTitleNode = (state: ManuscriptEditorState) => {
|
|
313
|
+
const altTitleNode = findChildrenByType(
|
|
314
|
+
state.doc,
|
|
315
|
+
state.schema.nodes.alt_titles
|
|
316
|
+
)[0]
|
|
317
|
+
if (altTitleNode) {
|
|
318
|
+
return altTitleNode
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
const titleNode = findChildrenByType(state.doc, state.schema.nodes.title)[0]
|
|
322
|
+
return titleNode
|
|
323
|
+
}
|
package/src/lib/view.ts
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* © 2024 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
|
+
ManuscriptEditorView,
|
|
19
|
+
ManuscriptNodeType,
|
|
20
|
+
schema,
|
|
21
|
+
} from '@manuscripts/transform'
|
|
22
|
+
import { Attrs } from 'prosemirror-model'
|
|
23
|
+
import { NodeSelection } from 'prosemirror-state'
|
|
24
|
+
import * as utils from 'prosemirror-utils'
|
|
25
|
+
|
|
26
|
+
import { isHidden } from './track-changes-utils'
|
|
27
|
+
import { sanitizeAttrsChange } from '@manuscripts/track-changes-plugin'
|
|
28
|
+
|
|
29
|
+
const metaNodeTypes = [
|
|
30
|
+
schema.nodes.bibliography_item,
|
|
31
|
+
schema.nodes.affiliation,
|
|
32
|
+
schema.nodes.contributor,
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
const updateMetaNode = 'track-changes-update-meta-node'
|
|
36
|
+
|
|
37
|
+
export const findChildByID = (
|
|
38
|
+
view: ManuscriptEditorView,
|
|
39
|
+
id: string
|
|
40
|
+
): utils.NodeWithPos | undefined => {
|
|
41
|
+
const doc = view.state.doc
|
|
42
|
+
const children = utils.findChildren(doc, (n) => n.attrs.id === id)
|
|
43
|
+
return children.length ? children[0] : undefined
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export const findChildByType = (
|
|
47
|
+
view: ManuscriptEditorView,
|
|
48
|
+
type: ManuscriptNodeType
|
|
49
|
+
): utils.NodeWithPos | undefined => {
|
|
50
|
+
const children = findChildrenByType(view, type)
|
|
51
|
+
return children.length ? children[0] : undefined
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export const findChildrenByType = (
|
|
55
|
+
view: ManuscriptEditorView,
|
|
56
|
+
type: ManuscriptNodeType
|
|
57
|
+
): utils.NodeWithPos[] => {
|
|
58
|
+
const doc = view.state.doc
|
|
59
|
+
return utils.findChildrenByType(doc, type).filter((n) => !isHidden(n.node))
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export const findChildrenAttrsByType = <T extends Attrs>(
|
|
63
|
+
view: ManuscriptEditorView,
|
|
64
|
+
type: ManuscriptNodeType
|
|
65
|
+
): T[] => {
|
|
66
|
+
return findChildrenByType(view, type).map((n) => n.node.attrs) as T[]
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export const updateNodeAttrs = (
|
|
70
|
+
view: ManuscriptEditorView,
|
|
71
|
+
type: ManuscriptNodeType,
|
|
72
|
+
attrs: Attrs
|
|
73
|
+
) => {
|
|
74
|
+
const child = findChildByID(view, attrs.id)
|
|
75
|
+
if (child) {
|
|
76
|
+
const copy = sanitizeAttrsChange(attrs, child.node.attrs)
|
|
77
|
+
// @ts-ignore attrs readonly - deleting from a copy
|
|
78
|
+
delete copy.dataTracked
|
|
79
|
+
const pos = child.pos
|
|
80
|
+
const tr = view.state.tr
|
|
81
|
+
tr.setNodeMarkup(pos, undefined, copy).setSelection(
|
|
82
|
+
NodeSelection.create(tr.doc, pos)
|
|
83
|
+
)
|
|
84
|
+
if (metaNodeTypes.includes(type)) {
|
|
85
|
+
tr.setMeta(updateMetaNode, true)
|
|
86
|
+
}
|
|
87
|
+
view.dispatch(tr)
|
|
88
|
+
return true
|
|
89
|
+
}
|
|
90
|
+
return false
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export const deleteNode = (view: ManuscriptEditorView, id: string) => {
|
|
94
|
+
const child = findChildByID(view, id)
|
|
95
|
+
if (child) {
|
|
96
|
+
const pos = child.pos
|
|
97
|
+
const node = child.node
|
|
98
|
+
view.dispatch(view.state.tr.delete(pos, pos + node.nodeSize))
|
|
99
|
+
}
|
|
100
|
+
}
|