@manuscripts/body-editor 3.17.2 → 3.17.5
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/commands.js +37 -21
- package/dist/cjs/components/references/ReferenceSearch.js +1 -1
- package/dist/cjs/configs/editor-views.js +1 -0
- package/dist/cjs/lib/__tests__/plugins.test.js +1 -1
- package/dist/cjs/lib/context-menu.js +4 -1
- package/dist/cjs/menus.js +1 -1
- package/dist/cjs/node-type-icons.js +1 -0
- package/dist/cjs/plugins/section_category.js +5 -2
- package/dist/cjs/plugins/translations.js +8 -20
- package/dist/cjs/versions.js +1 -1
- package/dist/cjs/views/link_editable.js +55 -4
- package/dist/es/commands.js +34 -19
- package/dist/es/components/references/ReferenceSearch.js +1 -1
- package/dist/es/configs/editor-views.js +1 -0
- package/dist/es/lib/__tests__/plugins.test.js +1 -1
- package/dist/es/lib/context-menu.js +4 -1
- package/dist/es/menus.js +1 -1
- package/dist/es/node-type-icons.js +1 -0
- package/dist/es/plugins/section_category.js +6 -3
- package/dist/es/plugins/translations.js +9 -21
- package/dist/es/versions.js +1 -1
- package/dist/es/views/link_editable.js +55 -4
- package/dist/types/commands.d.ts +3 -2
- package/dist/types/versions.d.ts +1 -1
- package/dist/types/views/link_editable.d.ts +5 -1
- package/package.json +3 -3
- package/src/commands.ts +56 -35
- package/src/components/references/ReferenceSearch.tsx +1 -8
- package/src/configs/editor-views.ts +1 -0
- package/src/lib/__tests__/plugins.test.ts +1 -1
- package/src/lib/context-menu.ts +4 -1
- package/src/menus.tsx +1 -1
- package/src/node-type-icons.tsx +1 -0
- package/src/plugins/section_category.ts +7 -2
- package/src/plugins/translations.ts +16 -27
- package/src/versions.ts +1 -1
- package/src/views/link_editable.ts +73 -4
- package/styles/Editor.css +7 -0
package/dist/es/versions.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const VERSION = '3.17.
|
|
1
|
+
export const VERSION = '3.17.5';
|
|
2
2
|
export const MATHJAX_VERSION = '3.2.2';
|
|
@@ -13,14 +13,16 @@
|
|
|
13
13
|
* See the License for the specific language governing permissions and
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
|
+
import { ContextMenu } from '@manuscripts/style-guide';
|
|
17
|
+
import { isDeleted } from '@manuscripts/track-changes-plugin';
|
|
16
18
|
import { schema } from '@manuscripts/transform';
|
|
17
19
|
import { TextSelection } from 'prosemirror-state';
|
|
20
|
+
import { convertLinkToSupplementWeblink } from '../commands';
|
|
18
21
|
import { LinkForm, } from '../components/views/LinkForm';
|
|
19
22
|
import { allowedHref } from '../lib/url';
|
|
20
23
|
import { createEditableNodeView } from './creators';
|
|
21
24
|
import { LinkView } from './link';
|
|
22
25
|
import ReactSubView from './ReactSubView';
|
|
23
|
-
import { isDeleted } from '@manuscripts/track-changes-plugin';
|
|
24
26
|
export class LinkEditableView extends LinkView {
|
|
25
27
|
constructor() {
|
|
26
28
|
super(...arguments);
|
|
@@ -35,7 +37,7 @@ export class LinkEditableView extends LinkView {
|
|
|
35
37
|
this.dom.addEventListener('click', this.handleClick);
|
|
36
38
|
};
|
|
37
39
|
this.selectNode = () => {
|
|
38
|
-
if (!isDeleted(this.node)) {
|
|
40
|
+
if (!isDeleted(this.node) && !this.node.attrs.href) {
|
|
39
41
|
this.showForm();
|
|
40
42
|
}
|
|
41
43
|
};
|
|
@@ -45,6 +47,50 @@ export class LinkEditableView extends LinkView {
|
|
|
45
47
|
this.deselectNode = () => {
|
|
46
48
|
this.closeForm();
|
|
47
49
|
};
|
|
50
|
+
this.showContextMenu = () => {
|
|
51
|
+
if (!this.props.getCapabilities().editArticle) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
this.closeForm();
|
|
55
|
+
const href = this.node.attrs.href;
|
|
56
|
+
const componentProps = {
|
|
57
|
+
actions: [
|
|
58
|
+
{
|
|
59
|
+
label: 'Edit',
|
|
60
|
+
action: this.handleEdit,
|
|
61
|
+
icon: 'Edit',
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
label: 'Convert to Weblink',
|
|
65
|
+
action: this.handleConvertToWebLink,
|
|
66
|
+
icon: 'ConvertToWebLink',
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
label: 'Open Link',
|
|
70
|
+
action: this.handleOpenLink,
|
|
71
|
+
icon: 'ExternalLink',
|
|
72
|
+
disabled: !allowedHref(href),
|
|
73
|
+
},
|
|
74
|
+
],
|
|
75
|
+
};
|
|
76
|
+
this.popperContainer = ReactSubView(this.props, ContextMenu, componentProps, this.node, this.getPos, this.view, ['context-menu', 'link-context-menu']);
|
|
77
|
+
this.props.popper.show(this.dom, this.popperContainer, 'bottom');
|
|
78
|
+
};
|
|
79
|
+
this.handleEdit = () => {
|
|
80
|
+
this.closeForm();
|
|
81
|
+
this.showForm();
|
|
82
|
+
};
|
|
83
|
+
this.handleConvertToWebLink = () => {
|
|
84
|
+
this.closeForm();
|
|
85
|
+
convertLinkToSupplementWeblink(this.getPos(), this.node, this.view);
|
|
86
|
+
};
|
|
87
|
+
this.handleOpenLink = () => {
|
|
88
|
+
const href = this.node.attrs.href;
|
|
89
|
+
if (allowedHref(href)) {
|
|
90
|
+
window.open(href, '_blank', 'noopener,noreferrer');
|
|
91
|
+
}
|
|
92
|
+
this.closeForm();
|
|
93
|
+
};
|
|
48
94
|
this.showForm = () => {
|
|
49
95
|
if (!this.props.getCapabilities().editArticle) {
|
|
50
96
|
return;
|
|
@@ -65,9 +111,14 @@ export class LinkEditableView extends LinkView {
|
|
|
65
111
|
this.props.popper.show(this.dom, this.popperContainer, 'bottom');
|
|
66
112
|
};
|
|
67
113
|
this.handleClick = (e) => {
|
|
68
|
-
if (this.props.getCapabilities().editArticle) {
|
|
69
|
-
|
|
114
|
+
if (!this.props.getCapabilities().editArticle) {
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
e.preventDefault();
|
|
118
|
+
if (isDeleted(this.node) || !this.node.attrs.href) {
|
|
119
|
+
return;
|
|
70
120
|
}
|
|
121
|
+
this.showContextMenu();
|
|
71
122
|
};
|
|
72
123
|
this.handleCancel = () => {
|
|
73
124
|
const attrs = this.node.attrs;
|
package/dist/types/commands.d.ts
CHANGED
|
@@ -35,6 +35,7 @@ export declare const insertEmbed: (state: ManuscriptEditorState, dispatch?: Disp
|
|
|
35
35
|
export declare const insertTable: (config: TableConfig, state: ManuscriptEditorState, dispatch?: Dispatch) => boolean;
|
|
36
36
|
export declare const insertSupplement: (file: FileAttachment, view: ManuscriptEditorView, setSelection?: boolean) => boolean;
|
|
37
37
|
export declare const insertSupplementWeblink: (url: string, title: string, view: ManuscriptEditorView) => boolean;
|
|
38
|
+
export declare const convertLinkToSupplementWeblink: (pos: number, node: ManuscriptNode, view: ManuscriptEditorView) => boolean;
|
|
38
39
|
export declare const updateSupplementWeblink: (pos: number, url: string, title: string, view: ManuscriptEditorView) => boolean;
|
|
39
40
|
export declare const insertAttachment: (file: FileAttachment, state: ManuscriptEditorState, type: string, dispatch?: Dispatch) => boolean;
|
|
40
41
|
export declare const insertBlock: (nodeType: ManuscriptNodeType) => (state: ManuscriptEditorState, dispatch?: Dispatch) => boolean;
|
|
@@ -66,8 +67,8 @@ export declare const insertKeywords: (state: ManuscriptEditorState, dispatch?: D
|
|
|
66
67
|
export declare const insertList: (type: ManuscriptNodeType, style?: string) => (state: ManuscriptEditorState, dispatch?: Dispatch, view?: EditorView) => boolean;
|
|
67
68
|
export declare const insertBibliographySection: () => boolean;
|
|
68
69
|
export declare const insertTOCSection: () => boolean;
|
|
69
|
-
export declare const insertTransAbstract: (state: ManuscriptEditorState, dispatch?: Dispatch, category?: string
|
|
70
|
-
export declare const insertTransGraphicalAbstract: (category: SectionCategory
|
|
70
|
+
export declare const insertTransAbstract: (state: ManuscriptEditorState, dispatch?: Dispatch, category?: string) => boolean;
|
|
71
|
+
export declare const insertTransGraphicalAbstract: (category: SectionCategory) => (state: ManuscriptEditorState, dispatch?: Dispatch, view?: EditorView) => boolean;
|
|
71
72
|
export declare const isAtStartOfTextBlock: (state: ManuscriptEditorState, $cursor: ResolvedPos, view?: ManuscriptEditorView) => boolean;
|
|
72
73
|
export declare const isTextSelection: (selection: Selection) => selection is ManuscriptTextSelection;
|
|
73
74
|
export declare const ignoreAtomBlockNodeBackward: (state: ManuscriptEditorState, dispatch?: Dispatch, view?: ManuscriptEditorView) => boolean;
|
package/dist/types/versions.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const VERSION = "3.17.
|
|
1
|
+
export declare const VERSION = "3.17.5";
|
|
2
2
|
export declare const MATHJAX_VERSION = "3.2.2";
|
|
@@ -23,6 +23,10 @@ export declare class LinkEditableView extends LinkView {
|
|
|
23
23
|
selectNode: () => void;
|
|
24
24
|
destroy: () => void;
|
|
25
25
|
deselectNode: () => void;
|
|
26
|
+
private showContextMenu;
|
|
27
|
+
private handleEdit;
|
|
28
|
+
private handleConvertToWebLink;
|
|
29
|
+
private handleOpenLink;
|
|
26
30
|
private showForm;
|
|
27
31
|
private handleClick;
|
|
28
32
|
private handleCancel;
|
|
@@ -31,5 +35,5 @@ export declare class LinkEditableView extends LinkView {
|
|
|
31
35
|
private removeLink;
|
|
32
36
|
private closeForm;
|
|
33
37
|
}
|
|
34
|
-
declare const _default: (props: import("../configs/ManuscriptsEditor").EditorProps, dispatch?: import("
|
|
38
|
+
declare const _default: (props: import("../configs/ManuscriptsEditor").EditorProps, dispatch?: import("../commands").Dispatch) => import("../types").NodeViewCreator<LinkEditableView>;
|
|
35
39
|
export default _default;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@manuscripts/body-editor",
|
|
3
3
|
"description": "Prosemirror components for editing and viewing manuscripts",
|
|
4
|
-
"version": "3.17.
|
|
4
|
+
"version": "3.17.5",
|
|
5
5
|
"repository": "github:Atypon-OpenSource/manuscripts-body-editor",
|
|
6
6
|
"license": "Apache-2.0",
|
|
7
7
|
"main": "dist/cjs",
|
|
@@ -41,9 +41,9 @@
|
|
|
41
41
|
"@citation-js/plugin-pubmed": "0.3.0",
|
|
42
42
|
"@citation-js/plugin-ris": "0.7.18",
|
|
43
43
|
"@iarna/word-count": "1.1.2",
|
|
44
|
-
"@manuscripts/style-guide": "3.7.
|
|
44
|
+
"@manuscripts/style-guide": "3.7.2",
|
|
45
45
|
"@manuscripts/track-changes-plugin": "2.4.0",
|
|
46
|
-
"@manuscripts/transform": "4.5.
|
|
46
|
+
"@manuscripts/transform": "4.5.4",
|
|
47
47
|
"@popperjs/core": "2.11.8",
|
|
48
48
|
"citeproc": "2.4.63",
|
|
49
49
|
"codemirror": "5.65.19",
|
package/src/commands.ts
CHANGED
|
@@ -543,6 +543,40 @@ export const insertSupplementWeblink = (
|
|
|
543
543
|
return true
|
|
544
544
|
}
|
|
545
545
|
|
|
546
|
+
export const convertLinkToSupplementWeblink = (
|
|
547
|
+
pos: number,
|
|
548
|
+
node: ManuscriptNode,
|
|
549
|
+
view: ManuscriptEditorView
|
|
550
|
+
) => {
|
|
551
|
+
const href = node.attrs.href
|
|
552
|
+
if (!href) {
|
|
553
|
+
return false
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
const text = node.textContent.trim()
|
|
557
|
+
const id = generateNodeID(schema.nodes.supplement)
|
|
558
|
+
|
|
559
|
+
const supplement = schema.nodes.supplement.createAndFill(
|
|
560
|
+
{ id, href },
|
|
561
|
+
createAndFillCaption()
|
|
562
|
+
) as SupplementNode
|
|
563
|
+
|
|
564
|
+
const crossReference = schema.nodes.cross_reference.create({
|
|
565
|
+
id: generateNodeID(schema.nodes.cross_reference),
|
|
566
|
+
rids: [id],
|
|
567
|
+
label: text,
|
|
568
|
+
})
|
|
569
|
+
|
|
570
|
+
const tr = view.state.tr
|
|
571
|
+
tr.replaceWith(pos, pos + node.nodeSize, crossReference)
|
|
572
|
+
upsertSupplementsSection(tr, supplement)
|
|
573
|
+
tr.setSelection(TextSelection.create(tr.doc, pos))
|
|
574
|
+
|
|
575
|
+
view.focus()
|
|
576
|
+
view.dispatch(tr)
|
|
577
|
+
return true
|
|
578
|
+
}
|
|
579
|
+
|
|
546
580
|
export const updateSupplementWeblink = (
|
|
547
581
|
pos: number,
|
|
548
582
|
url: string,
|
|
@@ -1109,24 +1143,20 @@ export const insertAbstractSection =
|
|
|
1109
1143
|
return false
|
|
1110
1144
|
}
|
|
1111
1145
|
const abstracts = findAbstractsNode(state.doc)
|
|
1112
|
-
const
|
|
1113
|
-
|
|
1114
|
-
|
|
1146
|
+
const abstractNodes = findChildrenByType(
|
|
1147
|
+
abstracts.node,
|
|
1148
|
+
schema.nodes.abstract
|
|
1149
|
+
)
|
|
1150
|
+
if (abstractNodes.some((s) => s.node.attrs.category === category.id)) {
|
|
1115
1151
|
return false
|
|
1116
1152
|
}
|
|
1117
1153
|
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
)[0]
|
|
1123
|
-
|
|
1124
|
-
let pos = ga ? ga.pos : abstracts.pos + abstracts.node.content.size + 1
|
|
1125
|
-
if (category.id === 'abstract') {
|
|
1126
|
-
pos = abstracts.pos + 1
|
|
1127
|
-
}
|
|
1154
|
+
const pos =
|
|
1155
|
+
findInsertionPosition(schema.nodes.abstract, abstracts.node) +
|
|
1156
|
+
abstracts.pos +
|
|
1157
|
+
1
|
|
1128
1158
|
|
|
1129
|
-
const node = schema.nodes.
|
|
1159
|
+
const node = schema.nodes.abstract.create({ category: category.id }, [
|
|
1130
1160
|
schema.nodes.section_title.create({}, schema.text(category.titles[0])),
|
|
1131
1161
|
schema.nodes.paragraph.create({ placeholder: 'Type abstract here...' }),
|
|
1132
1162
|
])
|
|
@@ -1204,15 +1234,13 @@ export const insertGraphicalAbstract =
|
|
|
1204
1234
|
return false
|
|
1205
1235
|
}
|
|
1206
1236
|
|
|
1207
|
-
const
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
// abstract-key-image insert before abstract-graphical
|
|
1215
|
-
pos = ga && category.id === 'abstract-key-image' ? ga.pos : pos
|
|
1237
|
+
const pos =
|
|
1238
|
+
findInsertionPosition(
|
|
1239
|
+
schema.nodes.graphical_abstract_section,
|
|
1240
|
+
abstracts.node
|
|
1241
|
+
) +
|
|
1242
|
+
abstracts.pos +
|
|
1243
|
+
1
|
|
1216
1244
|
|
|
1217
1245
|
const node = schema.nodes.graphical_abstract_section.createAndFill(
|
|
1218
1246
|
{ category: category.id },
|
|
@@ -1503,8 +1531,7 @@ export const insertTOCSection = () => {
|
|
|
1503
1531
|
export const insertTransAbstract = (
|
|
1504
1532
|
state: ManuscriptEditorState,
|
|
1505
1533
|
dispatch?: Dispatch,
|
|
1506
|
-
category?: string
|
|
1507
|
-
insertAfterPos?: number
|
|
1534
|
+
category?: string
|
|
1508
1535
|
) => {
|
|
1509
1536
|
if (!templateAllows(state, schema.nodes.trans_abstract)) {
|
|
1510
1537
|
return false
|
|
@@ -1532,11 +1559,8 @@ export const insertTransAbstract = (
|
|
|
1532
1559
|
)
|
|
1533
1560
|
|
|
1534
1561
|
const abstracts = findAbstractsNode(state.doc)
|
|
1535
|
-
|
|
1536
|
-
const pos =
|
|
1537
|
-
insertAfterPos != null
|
|
1538
|
-
? insertAfterPos
|
|
1539
|
-
: abstracts.pos + abstracts.node.nodeSize - 1
|
|
1562
|
+
// append at the end of the abstracts node, not just the first valid-but-earlier slot.
|
|
1563
|
+
const pos = abstracts.node.content.size + abstracts.pos + 1
|
|
1540
1564
|
const tr = state.tr.insert(pos, node)
|
|
1541
1565
|
|
|
1542
1566
|
const selection = TextSelection.create(tr.doc, pos + 1)
|
|
@@ -1547,7 +1571,7 @@ export const insertTransAbstract = (
|
|
|
1547
1571
|
}
|
|
1548
1572
|
|
|
1549
1573
|
export const insertTransGraphicalAbstract =
|
|
1550
|
-
(category: SectionCategory
|
|
1574
|
+
(category: SectionCategory) =>
|
|
1551
1575
|
(state: ManuscriptEditorState, dispatch?: Dispatch, view?: EditorView) => {
|
|
1552
1576
|
if (!templateAllows(state, schema.nodes.trans_graphical_abstract)) {
|
|
1553
1577
|
return false
|
|
@@ -1559,10 +1583,7 @@ export const insertTransGraphicalAbstract =
|
|
|
1559
1583
|
const lang = state.doc.attrs.primaryLanguageCode || 'en'
|
|
1560
1584
|
|
|
1561
1585
|
const abstracts = findAbstractsNode(state.doc)
|
|
1562
|
-
const pos =
|
|
1563
|
-
insertAfterPos != null
|
|
1564
|
-
? insertAfterPos
|
|
1565
|
-
: abstracts.pos + abstracts.node.content.size + 1
|
|
1586
|
+
const pos = abstracts.node.content.size + abstracts.pos + 1
|
|
1566
1587
|
|
|
1567
1588
|
const node = schema.nodes.trans_graphical_abstract.createAndFill(
|
|
1568
1589
|
{
|
|
@@ -75,14 +75,7 @@ export const ReferenceSearch: React.FC<{
|
|
|
75
75
|
onAdd: () => void
|
|
76
76
|
onCite: (items: BibliographyItemAttrs[]) => void
|
|
77
77
|
onCancel: () => void
|
|
78
|
-
}> = ({
|
|
79
|
-
query: initialQuery,
|
|
80
|
-
sources,
|
|
81
|
-
items,
|
|
82
|
-
onAdd,
|
|
83
|
-
onCite,
|
|
84
|
-
onCancel,
|
|
85
|
-
}) => {
|
|
78
|
+
}> = ({ query: initialQuery, sources, items, onAdd, onCite, onCancel }) => {
|
|
86
79
|
const [query, setQuery] = useState<string>(initialQuery || '')
|
|
87
80
|
const [selections, setSelections] = useState(
|
|
88
81
|
new Map<string, BibliographyItemAttrs>()
|
|
@@ -137,6 +137,7 @@ export default (
|
|
|
137
137
|
headshot_element: headshotElement(props, dispatch),
|
|
138
138
|
headshot_image: headshotImage(props, dispatch),
|
|
139
139
|
abstracts: abstracts(props),
|
|
140
|
+
abstract: section(props),
|
|
140
141
|
trans_abstract: transAbstract(props),
|
|
141
142
|
trans_graphical_abstract: transGraphicalAbstract(props),
|
|
142
143
|
attachment: attachment(props, dispatch),
|
package/src/lib/context-menu.ts
CHANGED
|
@@ -397,7 +397,10 @@ export class ContextMenu {
|
|
|
397
397
|
this.createMenuSection((section: HTMLElement) => {
|
|
398
398
|
let nodeName = nodeNames.get(type) || ''
|
|
399
399
|
if (type === schema.nodes.section_title) {
|
|
400
|
-
|
|
400
|
+
const containerType = $pos.parent.type
|
|
401
|
+
nodeName =
|
|
402
|
+
nodeNames.get(containerType) ??
|
|
403
|
+
(nodeNames.get(schema.nodes.section) as string)
|
|
401
404
|
}
|
|
402
405
|
section.appendChild(
|
|
403
406
|
this.createMenuItem(`Delete ${nodeName}`, () => {
|
package/src/menus.tsx
CHANGED
|
@@ -563,7 +563,7 @@ export const getEditorMenus = (
|
|
|
563
563
|
const abstractSection = allAbstractsCategories.find(
|
|
564
564
|
(s) => s.id === ABSTRACT_ID
|
|
565
565
|
)
|
|
566
|
-
const ABSTRACT_GRAPHICAL_ID = '
|
|
566
|
+
const ABSTRACT_GRAPHICAL_ID = 'graphical'
|
|
567
567
|
const graphicalAbstractSection = allAbstractsCategories.find(
|
|
568
568
|
(s) => s.id === ABSTRACT_GRAPHICAL_ID
|
|
569
569
|
)
|
package/src/node-type-icons.tsx
CHANGED
|
@@ -69,6 +69,7 @@ const icons: Map<
|
|
|
69
69
|
[nodes.paragraph, OutlineParagraphIcon],
|
|
70
70
|
[nodes.pullquote_element, OutlinePullQuoteIcon],
|
|
71
71
|
[nodes.section, OutlineSectionIcon],
|
|
72
|
+
[nodes.abstract, OutlineSectionIcon],
|
|
72
73
|
[nodes.table_element, OutlineTableIcon],
|
|
73
74
|
[nodes.graphical_abstract_section, OutlineSectionIcon],
|
|
74
75
|
[nodes.trans_graphical_abstract, OutlineSectionIcon],
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
*/
|
|
16
16
|
import {
|
|
17
17
|
getGroupCategories,
|
|
18
|
+
isAbstractNode,
|
|
18
19
|
isSectionNode,
|
|
19
20
|
schema,
|
|
20
21
|
SectionCategory,
|
|
@@ -154,7 +155,8 @@ const buildPluginState = (
|
|
|
154
155
|
if (node.type === schema.nodes.box_element) {
|
|
155
156
|
return false
|
|
156
157
|
}
|
|
157
|
-
|
|
158
|
+
|
|
159
|
+
if (isSectionNode(node) || isAbstractNode(node)) {
|
|
158
160
|
const categoryID = node.attrs.category
|
|
159
161
|
const category = categories.get(categoryID)
|
|
160
162
|
const $pos = state.doc.resolve(pos)
|
|
@@ -191,7 +193,10 @@ const buildPluginState = (
|
|
|
191
193
|
}
|
|
192
194
|
|
|
193
195
|
const getUsedSectionCategoryIDs = (state: EditorState): Set<string> => {
|
|
194
|
-
const sections =
|
|
196
|
+
const sections = [
|
|
197
|
+
...findChildrenByType(state.doc, schema.nodes.section),
|
|
198
|
+
...findChildrenByType(state.doc, schema.nodes.abstract),
|
|
199
|
+
]
|
|
195
200
|
const used = new Set<string>()
|
|
196
201
|
sections.forEach(({ node }) => {
|
|
197
202
|
if (node.attrs.category) {
|
|
@@ -14,8 +14,13 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
import {
|
|
18
|
-
|
|
17
|
+
import {
|
|
18
|
+
isAbstractNode,
|
|
19
|
+
isGraphicalAbstractSectionNode,
|
|
20
|
+
isTransAbstractNode,
|
|
21
|
+
isTransGraphicalAbstractNode,
|
|
22
|
+
schema,
|
|
23
|
+
} from '@manuscripts/transform'
|
|
19
24
|
import { Plugin } from 'prosemirror-state'
|
|
20
25
|
import { Decoration, DecorationSet } from 'prosemirror-view'
|
|
21
26
|
|
|
@@ -23,11 +28,11 @@ import { insertTransAbstract, insertTransGraphicalAbstract } from '../commands'
|
|
|
23
28
|
import { EditorProps } from '../configs/ManuscriptsEditor'
|
|
24
29
|
import { addAuthorIcon, translateIcon } from '../icons'
|
|
25
30
|
import { getLanguage, getLanguageLabel } from '../lib/languages'
|
|
26
|
-
import { templateAllows } from '../lib/template'
|
|
27
31
|
import {
|
|
28
|
-
handleEnterKey,
|
|
29
32
|
createKeyboardInteraction,
|
|
33
|
+
handleEnterKey,
|
|
30
34
|
} from '../lib/navigation-utils'
|
|
35
|
+
import { templateAllows } from '../lib/template'
|
|
31
36
|
|
|
32
37
|
const createMenuItem = (
|
|
33
38
|
props: EditorProps,
|
|
@@ -90,11 +95,6 @@ const createLanguageMenu = (
|
|
|
90
95
|
return { menu, destroy }
|
|
91
96
|
}
|
|
92
97
|
|
|
93
|
-
const getInsertionPos = (doc: Node, nodePos: number): number | null => {
|
|
94
|
-
const node = doc.nodeAt(nodePos)
|
|
95
|
-
return node ? nodePos + node.nodeSize : null
|
|
96
|
-
}
|
|
97
|
-
|
|
98
98
|
export default (props: EditorProps) =>
|
|
99
99
|
new Plugin<null>({
|
|
100
100
|
props: {
|
|
@@ -110,19 +110,14 @@ export default (props: EditorProps) =>
|
|
|
110
110
|
|
|
111
111
|
const widgets: Decoration[] = []
|
|
112
112
|
|
|
113
|
-
state.doc.descendants((node, pos
|
|
113
|
+
state.doc.descendants((node, pos) => {
|
|
114
114
|
const isAbstractSection =
|
|
115
|
-
(node
|
|
116
|
-
node.type === schema.nodes.graphical_abstract_section) &&
|
|
117
|
-
parent?.type === schema.nodes.abstracts
|
|
115
|
+
isAbstractNode(node) || isGraphicalAbstractSectionNode(node)
|
|
118
116
|
|
|
119
117
|
// Show "Add translation" for abstract sections
|
|
120
118
|
if (isAbstractSection) {
|
|
121
|
-
const isGraphical =
|
|
122
|
-
node.type === schema.nodes.graphical_abstract_section
|
|
123
119
|
const category = props.sectionCategories.get(node.attrs.category)
|
|
124
|
-
|
|
125
|
-
const canEdit = isGraphical
|
|
120
|
+
const canEdit = isGraphicalAbstractSectionNode(node)
|
|
126
121
|
? canEditTransGraphicalAbstract &&
|
|
127
122
|
category &&
|
|
128
123
|
insertTransGraphicalAbstract(category)(state)
|
|
@@ -142,12 +137,8 @@ export default (props: EditorProps) =>
|
|
|
142
137
|
const handleActivate = (event: Event) => {
|
|
143
138
|
event.preventDefault()
|
|
144
139
|
event.stopPropagation()
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
return
|
|
148
|
-
}
|
|
149
|
-
if (isGraphical && category) {
|
|
150
|
-
insertTransGraphicalAbstract(category, insertPos)(
|
|
140
|
+
if (isGraphicalAbstractSectionNode(node) && category) {
|
|
141
|
+
insertTransGraphicalAbstract(category)(
|
|
151
142
|
view.state,
|
|
152
143
|
view.dispatch,
|
|
153
144
|
view
|
|
@@ -156,8 +147,7 @@ export default (props: EditorProps) =>
|
|
|
156
147
|
insertTransAbstract(
|
|
157
148
|
view.state,
|
|
158
149
|
view.dispatch,
|
|
159
|
-
node.attrs.category
|
|
160
|
-
insertPos
|
|
150
|
+
node.attrs.category
|
|
161
151
|
)
|
|
162
152
|
}
|
|
163
153
|
}
|
|
@@ -177,8 +167,7 @@ export default (props: EditorProps) =>
|
|
|
177
167
|
|
|
178
168
|
// Language selector for trans_abstract and trans_graphical_abstract nodes
|
|
179
169
|
const isTransNode =
|
|
180
|
-
node
|
|
181
|
-
node.type === schema.nodes.trans_graphical_abstract
|
|
170
|
+
isTransAbstractNode(node) || isTransGraphicalAbstractNode(node)
|
|
182
171
|
|
|
183
172
|
if (isTransNode) {
|
|
184
173
|
const canEdit =
|
package/src/versions.ts
CHANGED
|
@@ -14,9 +14,12 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
+
import { ContextMenu, ContextMenuProps } from '@manuscripts/style-guide'
|
|
18
|
+
import { isDeleted } from '@manuscripts/track-changes-plugin'
|
|
17
19
|
import { schema } from '@manuscripts/transform'
|
|
18
20
|
import { TextSelection } from 'prosemirror-state'
|
|
19
21
|
|
|
22
|
+
import { convertLinkToSupplementWeblink } from '../commands'
|
|
20
23
|
import {
|
|
21
24
|
LinkForm,
|
|
22
25
|
LinkFormProps,
|
|
@@ -26,7 +29,6 @@ import { allowedHref } from '../lib/url'
|
|
|
26
29
|
import { createEditableNodeView } from './creators'
|
|
27
30
|
import { LinkView } from './link'
|
|
28
31
|
import ReactSubView from './ReactSubView'
|
|
29
|
-
import { isDeleted } from '@manuscripts/track-changes-plugin'
|
|
30
32
|
|
|
31
33
|
export class LinkEditableView extends LinkView {
|
|
32
34
|
protected popperContainer: HTMLDivElement
|
|
@@ -59,7 +61,7 @@ export class LinkEditableView extends LinkView {
|
|
|
59
61
|
}
|
|
60
62
|
|
|
61
63
|
public selectNode = () => {
|
|
62
|
-
if (!isDeleted(this.node)) {
|
|
64
|
+
if (!isDeleted(this.node) && !this.node.attrs.href) {
|
|
63
65
|
this.showForm()
|
|
64
66
|
}
|
|
65
67
|
}
|
|
@@ -72,6 +74,67 @@ export class LinkEditableView extends LinkView {
|
|
|
72
74
|
this.closeForm()
|
|
73
75
|
}
|
|
74
76
|
|
|
77
|
+
private showContextMenu = () => {
|
|
78
|
+
if (!this.props.getCapabilities().editArticle) {
|
|
79
|
+
return
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
this.closeForm()
|
|
83
|
+
|
|
84
|
+
const href = this.node.attrs.href
|
|
85
|
+
|
|
86
|
+
const componentProps: ContextMenuProps = {
|
|
87
|
+
actions: [
|
|
88
|
+
{
|
|
89
|
+
label: 'Edit',
|
|
90
|
+
action: this.handleEdit,
|
|
91
|
+
icon: 'Edit',
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
label: 'Convert to Weblink',
|
|
95
|
+
action: this.handleConvertToWebLink,
|
|
96
|
+
icon: 'ConvertToWebLink',
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
label: 'Open Link',
|
|
100
|
+
action: this.handleOpenLink,
|
|
101
|
+
icon: 'ExternalLink',
|
|
102
|
+
disabled: !allowedHref(href),
|
|
103
|
+
},
|
|
104
|
+
],
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
this.popperContainer = ReactSubView(
|
|
108
|
+
this.props,
|
|
109
|
+
ContextMenu,
|
|
110
|
+
componentProps,
|
|
111
|
+
this.node,
|
|
112
|
+
this.getPos,
|
|
113
|
+
this.view,
|
|
114
|
+
['context-menu', 'link-context-menu']
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
this.props.popper.show(this.dom, this.popperContainer, 'bottom')
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
private handleEdit = () => {
|
|
121
|
+
this.closeForm()
|
|
122
|
+
this.showForm()
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
private handleConvertToWebLink = () => {
|
|
126
|
+
this.closeForm()
|
|
127
|
+
convertLinkToSupplementWeblink(this.getPos(), this.node, this.view)
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
private handleOpenLink = () => {
|
|
131
|
+
const href = this.node.attrs.href
|
|
132
|
+
if (allowedHref(href)) {
|
|
133
|
+
window.open(href, '_blank', 'noopener,noreferrer')
|
|
134
|
+
}
|
|
135
|
+
this.closeForm()
|
|
136
|
+
}
|
|
137
|
+
|
|
75
138
|
private showForm = () => {
|
|
76
139
|
if (!this.props.getCapabilities().editArticle) {
|
|
77
140
|
return
|
|
@@ -106,9 +169,15 @@ export class LinkEditableView extends LinkView {
|
|
|
106
169
|
}
|
|
107
170
|
|
|
108
171
|
private handleClick = (e: Event) => {
|
|
109
|
-
if (this.props.getCapabilities().editArticle) {
|
|
110
|
-
|
|
172
|
+
if (!this.props.getCapabilities().editArticle) {
|
|
173
|
+
return
|
|
174
|
+
}
|
|
175
|
+
e.preventDefault()
|
|
176
|
+
|
|
177
|
+
if (isDeleted(this.node) || !this.node.attrs.href) {
|
|
178
|
+
return
|
|
111
179
|
}
|
|
180
|
+
this.showContextMenu()
|
|
112
181
|
}
|
|
113
182
|
|
|
114
183
|
private handleCancel = () => {
|
package/styles/Editor.css
CHANGED
|
@@ -694,12 +694,14 @@
|
|
|
694
694
|
grid-template-columns: 52px auto 100px 28px;
|
|
695
695
|
}
|
|
696
696
|
.ProseMirror .block-container.block-section,
|
|
697
|
+
.ProseMirror .block-container.block-abstract,
|
|
697
698
|
.ProseMirror .block-container.block-graphical_abstract_section {
|
|
698
699
|
position: relative;
|
|
699
700
|
display: grid;
|
|
700
701
|
grid-template-columns: auto;
|
|
701
702
|
}
|
|
702
703
|
.ProseMirror .block-container.block-section section,
|
|
704
|
+
.ProseMirror .block-container.block-abstract section,
|
|
703
705
|
.ProseMirror .block-container.block-graphical_abstract_section section {
|
|
704
706
|
position: relative;
|
|
705
707
|
}
|
|
@@ -707,6 +709,7 @@
|
|
|
707
709
|
.ProseMirror
|
|
708
710
|
.block-container:not(
|
|
709
711
|
.block-section,
|
|
712
|
+
.block-abstract,
|
|
710
713
|
.block-graphical_abstract_section
|
|
711
714
|
):hover {
|
|
712
715
|
z-index: 2;
|
|
@@ -789,6 +792,7 @@
|
|
|
789
792
|
.block-container:not(
|
|
790
793
|
.block-section,
|
|
791
794
|
.block-box_element,
|
|
795
|
+
.block-abstract,
|
|
792
796
|
.block-graphical_abstract_section
|
|
793
797
|
):hover
|
|
794
798
|
.block-gutter,
|
|
@@ -796,6 +800,7 @@
|
|
|
796
800
|
.block-container:not(
|
|
797
801
|
.block-section,
|
|
798
802
|
.block-box_element,
|
|
803
|
+
.block-abstract,
|
|
799
804
|
.block-graphical_abstract_section
|
|
800
805
|
):focus-within
|
|
801
806
|
.block-gutter {
|
|
@@ -818,6 +823,7 @@
|
|
|
818
823
|
.block-container:not(
|
|
819
824
|
.block-section,
|
|
820
825
|
.block-box_element,
|
|
826
|
+
.block-abstract,
|
|
821
827
|
.block-graphical_abstract_section
|
|
822
828
|
):hover
|
|
823
829
|
.action-gutter,
|
|
@@ -825,6 +831,7 @@
|
|
|
825
831
|
.block-container:not(
|
|
826
832
|
.block-section,
|
|
827
833
|
.block-box_element,
|
|
834
|
+
.block-abstract,
|
|
828
835
|
.block-graphical_abstract_section
|
|
829
836
|
):focus-within
|
|
830
837
|
.action-gutter {
|