@manuscripts/body-editor 3.6.9 → 3.6.11
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 +12 -9
- package/dist/cjs/components/outline/DraggableTree.js +1 -0
- package/dist/cjs/configs/editor-views.js +4 -1
- package/dist/cjs/lib/doc.js +7 -5
- package/dist/cjs/lib/utils.js +4 -0
- package/dist/cjs/plugins/placeholder.js +3 -0
- package/dist/cjs/versions.js +1 -1
- package/dist/cjs/views/editable_block.js +1 -0
- package/dist/cjs/views/section_title.js +1 -0
- package/dist/cjs/views/supplement.js +175 -0
- package/dist/cjs/views/supplement_editable.js +20 -0
- package/dist/cjs/views/supplements.js +56 -0
- package/dist/cjs/views/supplements_editable.js +21 -0
- package/dist/es/commands.js +13 -10
- package/dist/es/components/outline/DraggableTree.js +1 -0
- package/dist/es/configs/editor-views.js +4 -1
- package/dist/es/lib/doc.js +5 -3
- package/dist/es/lib/utils.js +4 -0
- package/dist/es/plugins/placeholder.js +3 -0
- package/dist/es/versions.js +1 -1
- package/dist/es/views/editable_block.js +1 -0
- package/dist/es/views/section_title.js +1 -0
- package/dist/es/views/supplement.js +171 -0
- package/dist/es/views/supplement_editable.js +18 -0
- package/dist/es/views/supplements.js +49 -0
- package/dist/es/views/supplements_editable.js +19 -0
- package/dist/types/commands.d.ts +1 -1
- package/dist/types/lib/doc.d.ts +2 -2
- package/dist/types/versions.d.ts +1 -1
- package/dist/types/views/supplement.d.ts +37 -0
- package/dist/types/views/supplement_editable.d.ts +18 -0
- package/dist/types/views/supplements.d.ts +27 -0
- package/dist/types/views/supplements_editable.d.ts +44 -0
- package/package.json +2 -2
- package/styles/AdvancedEditor.css +14 -4
- package/styles/Editor.css +159 -0
package/dist/cjs/commands.js
CHANGED
|
@@ -297,18 +297,21 @@ const insertTable = (config, state, dispatch) => {
|
|
|
297
297
|
return true;
|
|
298
298
|
};
|
|
299
299
|
exports.insertTable = insertTable;
|
|
300
|
-
const insertSupplement = (file,
|
|
300
|
+
const insertSupplement = (file, view) => {
|
|
301
301
|
const supplement = transform_1.schema.nodes.supplement.createAndFill({
|
|
302
302
|
id: (0, transform_1.generateNodeID)(transform_1.schema.nodes.supplement),
|
|
303
303
|
href: file.id,
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
}
|
|
304
|
+
}, [
|
|
305
|
+
transform_1.schema.nodes.figcaption.create({}, [
|
|
306
|
+
transform_1.schema.nodes.caption_title.create(),
|
|
307
|
+
transform_1.schema.nodes.caption.create(),
|
|
308
|
+
]),
|
|
309
|
+
]);
|
|
310
|
+
const tr = view.state.tr;
|
|
311
|
+
const { pos } = (0, doc_1.upsertSupplementsSection)(tr, supplement);
|
|
312
|
+
tr.setSelection(prosemirror_state_1.NodeSelection.create(tr.doc, pos));
|
|
313
|
+
view.focus();
|
|
314
|
+
view.dispatch(tr.scrollIntoView());
|
|
312
315
|
return true;
|
|
313
316
|
};
|
|
314
317
|
exports.insertSupplement = insertSupplement;
|
|
@@ -63,6 +63,7 @@ const excludedTypes = [
|
|
|
63
63
|
transform_1.schema.nodes.trans_abstract,
|
|
64
64
|
transform_1.schema.nodes.subtitles,
|
|
65
65
|
transform_1.schema.nodes.subtitle,
|
|
66
|
+
transform_1.schema.nodes.supplements,
|
|
66
67
|
];
|
|
67
68
|
const childrenExcludedTypes = [
|
|
68
69
|
transform_1.schema.nodes.pullquote_element,
|
|
@@ -47,6 +47,8 @@ const section_label_1 = __importDefault(require("../views/section_label"));
|
|
|
47
47
|
const section_title_editable_1 = __importDefault(require("../views/section_title_editable"));
|
|
48
48
|
const subtitle_editable_1 = __importDefault(require("../views/subtitle_editable"));
|
|
49
49
|
const subtitles_editable_1 = __importDefault(require("../views/subtitles_editable"));
|
|
50
|
+
const supplement_editable_1 = __importDefault(require("../views/supplement_editable"));
|
|
51
|
+
const supplements_editable_1 = __importDefault(require("../views/supplements_editable"));
|
|
50
52
|
const table_cell_1 = __importDefault(require("../views/table_cell"));
|
|
51
53
|
const table_element_editable_1 = __importDefault(require("../views/table_element_editable"));
|
|
52
54
|
const table_element_footer_1 = __importDefault(require("../views/table_element_footer"));
|
|
@@ -96,7 +98,8 @@ exports.default = (props, dispatch) => {
|
|
|
96
98
|
table_header: (0, table_cell_1.default)(props),
|
|
97
99
|
table_element_footer: (0, table_element_footer_1.default)(props),
|
|
98
100
|
comments: (0, empty_1.default)('comments'),
|
|
99
|
-
supplements: (0,
|
|
101
|
+
supplements: (0, supplements_editable_1.default)(props, dispatch),
|
|
102
|
+
supplement: (0, supplement_editable_1.default)(props, dispatch),
|
|
100
103
|
author_notes: (0, author_notes_1.default)(props, dispatch),
|
|
101
104
|
awards: (0, awards_1.default)(props, dispatch),
|
|
102
105
|
award: (0, award_1.default)(props, dispatch),
|
package/dist/cjs/lib/doc.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.findNodeByID = exports.findGraphicalAbstractFigureElement = exports.findFootnotesSection = exports.findBibliographySection = exports.findBackmatter = exports.findBody = exports.findAbstractsNode = exports.insertFootnotesSection = exports.insertAttachmentsNode = exports.
|
|
3
|
+
exports.findNodeByID = exports.findGraphicalAbstractFigureElement = exports.findFootnotesSection = exports.findBibliographySection = exports.findBackmatter = exports.findBody = exports.findAbstractsNode = exports.insertFootnotesSection = exports.insertAttachmentsNode = exports.upsertSupplementsSection = exports.insertAwardsNode = void 0;
|
|
4
4
|
const transform_1 = require("@manuscripts/transform");
|
|
5
5
|
const prosemirror_utils_1 = require("prosemirror-utils");
|
|
6
6
|
const utils_1 = require("./utils");
|
|
@@ -19,21 +19,23 @@ const insertAwardsNode = (tr) => {
|
|
|
19
19
|
};
|
|
20
20
|
};
|
|
21
21
|
exports.insertAwardsNode = insertAwardsNode;
|
|
22
|
-
const
|
|
22
|
+
const upsertSupplementsSection = (tr, supplement) => {
|
|
23
23
|
const doc = tr.doc;
|
|
24
24
|
const supplements = (0, prosemirror_utils_1.findChildrenByType)(doc, transform_1.schema.nodes.supplements)[0];
|
|
25
25
|
if (supplements) {
|
|
26
|
-
|
|
26
|
+
const pos = supplements.pos + supplements.node.nodeSize - 1;
|
|
27
|
+
tr.insert(pos, supplement);
|
|
28
|
+
return { node: supplements.node, pos };
|
|
27
29
|
}
|
|
28
30
|
const pos = (0, utils_1.findInsertionPosition)(transform_1.schema.nodes.supplements, doc);
|
|
29
|
-
const node = transform_1.schema.nodes.supplements.createAndFill();
|
|
31
|
+
const node = transform_1.schema.nodes.supplements.createAndFill({ id: (0, transform_1.generateNodeID)(transform_1.schema.nodes.supplements) }, [supplement]);
|
|
30
32
|
tr.insert(pos, node);
|
|
31
33
|
return {
|
|
32
34
|
node,
|
|
33
35
|
pos,
|
|
34
36
|
};
|
|
35
37
|
};
|
|
36
|
-
exports.
|
|
38
|
+
exports.upsertSupplementsSection = upsertSupplementsSection;
|
|
37
39
|
const insertAttachmentsNode = (tr) => {
|
|
38
40
|
const attachmentsNodes = (0, prosemirror_utils_1.findChildrenByType)(tr.doc, transform_1.schema.nodes.attachments);
|
|
39
41
|
if (attachmentsNodes.length) {
|
package/dist/cjs/lib/utils.js
CHANGED
|
@@ -181,6 +181,10 @@ const findInsertionPosition = (type, doc) => {
|
|
|
181
181
|
insertPos = offset;
|
|
182
182
|
}
|
|
183
183
|
});
|
|
184
|
+
if (insertPos === 0 &&
|
|
185
|
+
doc.canReplaceWith(doc.childCount, doc.childCount, type)) {
|
|
186
|
+
insertPos = doc.content.size;
|
|
187
|
+
}
|
|
184
188
|
return insertPos;
|
|
185
189
|
};
|
|
186
190
|
exports.findInsertionPosition = findInsertionPosition;
|
|
@@ -84,6 +84,9 @@ exports.default = () => new prosemirror_state_1.Plugin({
|
|
|
84
84
|
if ((0, prosemirror_utils_1.findParentNodeOfTypeClosestToPos)($pos, transform_1.schema.nodes.box_element)) {
|
|
85
85
|
placeholderText = 'Optional box title...';
|
|
86
86
|
}
|
|
87
|
+
if ((0, prosemirror_utils_1.findParentNodeOfTypeClosestToPos)($pos, transform_1.schema.nodes.supplements)) {
|
|
88
|
+
placeholderText = 'Supplements';
|
|
89
|
+
}
|
|
87
90
|
decorations.push(prosemirror_view_1.Decoration.widget(pos + 1, placeholderWidget(placeholderText)));
|
|
88
91
|
}
|
|
89
92
|
else if (node.type === node.type.schema.nodes.trans_abstract) {
|
package/dist/cjs/versions.js
CHANGED
|
@@ -42,6 +42,7 @@ const EditableBlock = (Base) => {
|
|
|
42
42
|
const nodeType = this.node.type;
|
|
43
43
|
if (nodeType === transform_1.schema.nodes.hero_image ||
|
|
44
44
|
nodeType === transform_1.schema.nodes.subtitles ||
|
|
45
|
+
nodeType === transform_1.schema.nodes.supplements ||
|
|
45
46
|
(0, utils_1.hasParent)($pos, [
|
|
46
47
|
transform_1.schema.nodes.keywords,
|
|
47
48
|
transform_1.schema.nodes.bibliography_section,
|
|
@@ -32,6 +32,7 @@ class SectionTitleView extends block_view_1.default {
|
|
|
32
32
|
transform_1.schema.nodes.bibliography_section,
|
|
33
33
|
transform_1.schema.nodes.footnotes_section,
|
|
34
34
|
transform_1.schema.nodes.graphical_abstract_section,
|
|
35
|
+
transform_1.schema.nodes.supplements,
|
|
35
36
|
];
|
|
36
37
|
this.createElement = () => {
|
|
37
38
|
this.contentDOM = document.createElement(this.elementType);
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*!
|
|
3
|
+
* © 2025 Atypon Systems LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.SupplementView = void 0;
|
|
19
|
+
const style_guide_1 = require("@manuscripts/style-guide");
|
|
20
|
+
const server_1 = require("react-dom/server");
|
|
21
|
+
const icons_1 = require("../icons");
|
|
22
|
+
const doc_1 = require("../lib/doc");
|
|
23
|
+
const base_node_view_1 = require("./base_node_view");
|
|
24
|
+
const creators_1 = require("./creators");
|
|
25
|
+
class SupplementView extends base_node_view_1.BaseNodeView {
|
|
26
|
+
constructor() {
|
|
27
|
+
super(...arguments);
|
|
28
|
+
this.ignoreMutation = () => true;
|
|
29
|
+
this.createElement = () => {
|
|
30
|
+
this.dom = document.createElement('div');
|
|
31
|
+
this.dom.classList.add('supplement-item');
|
|
32
|
+
this.dom.classList.add('block');
|
|
33
|
+
this.dom.setAttribute('id', this.node.attrs.id);
|
|
34
|
+
this.dom.setAttribute('href', this.node.attrs.href);
|
|
35
|
+
this.dom.draggable = true;
|
|
36
|
+
this.contentDOM = document.createElement('div');
|
|
37
|
+
this.contentDOM.classList.add('supplement-caption');
|
|
38
|
+
this.dom.appendChild(this.contentDOM);
|
|
39
|
+
this.addFileInfo();
|
|
40
|
+
this.addDragIcon();
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
initialise() {
|
|
44
|
+
this.createElement();
|
|
45
|
+
this.updateContents();
|
|
46
|
+
this.setupDragAndDrop();
|
|
47
|
+
}
|
|
48
|
+
updateContents() {
|
|
49
|
+
super.updateContents();
|
|
50
|
+
this.refreshFileInfo();
|
|
51
|
+
}
|
|
52
|
+
getDropSide(element, clientY) {
|
|
53
|
+
const { top, bottom } = element.getBoundingClientRect();
|
|
54
|
+
const middleY = (top + bottom) / 2;
|
|
55
|
+
return clientY > middleY ? 'after' : 'before';
|
|
56
|
+
}
|
|
57
|
+
noActualMove(currentPos, nodeSize, targetPos) {
|
|
58
|
+
return targetPos === currentPos || targetPos === currentPos + nodeSize;
|
|
59
|
+
}
|
|
60
|
+
handleDragStart() {
|
|
61
|
+
const supplementId = this.node.attrs.id;
|
|
62
|
+
SupplementView.currentDragSupplementId = supplementId;
|
|
63
|
+
this.dom.classList.add('dragging');
|
|
64
|
+
}
|
|
65
|
+
setupDragAndDrop() {
|
|
66
|
+
const clearDropClasses = () => {
|
|
67
|
+
this.dom.classList.remove('drop-target-above', 'drop-target-below');
|
|
68
|
+
};
|
|
69
|
+
this.dom.addEventListener('dragstart', () => {
|
|
70
|
+
if (this.node.attrs.id) {
|
|
71
|
+
this.handleDragStart();
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
this.dom.addEventListener('dragend', () => {
|
|
75
|
+
SupplementView.currentDragSupplementId = null;
|
|
76
|
+
this.dom.classList.remove('dragging');
|
|
77
|
+
clearDropClasses();
|
|
78
|
+
});
|
|
79
|
+
this.dom.addEventListener('dragover', (e) => {
|
|
80
|
+
if (SupplementView.currentDragSupplementId) {
|
|
81
|
+
e.preventDefault();
|
|
82
|
+
e.stopPropagation();
|
|
83
|
+
const side = this.getDropSide(this.dom, e.clientY);
|
|
84
|
+
clearDropClasses();
|
|
85
|
+
this.dom.classList.add(side === 'before' ? 'drop-target-above' : 'drop-target-below');
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
this.dom.addEventListener('dragleave', (e) => {
|
|
89
|
+
if (!this.dom.contains(e.relatedTarget)) {
|
|
90
|
+
clearDropClasses();
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
this.dom.addEventListener('drop', (e) => {
|
|
94
|
+
if (!SupplementView.currentDragSupplementId) {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
e.preventDefault();
|
|
98
|
+
e.stopPropagation();
|
|
99
|
+
const supplementId = SupplementView.currentDragSupplementId;
|
|
100
|
+
if (!supplementId) {
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
const { state } = this.view;
|
|
104
|
+
const supplement = (0, doc_1.findNodeByID)(state.doc, supplementId);
|
|
105
|
+
if (!supplement) {
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
const toPos = this.getPos();
|
|
109
|
+
const side = this.getDropSide(this.dom, e.clientY);
|
|
110
|
+
const targetPos = side === 'before' ? toPos : toPos + this.node.nodeSize;
|
|
111
|
+
if (this.noActualMove(supplement.pos, supplement.node.nodeSize, targetPos)) {
|
|
112
|
+
clearDropClasses();
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
this.moveSupplement(supplement.pos, supplement.node, targetPos);
|
|
116
|
+
clearDropClasses();
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
moveSupplement(fromPos, fromNode, targetPos) {
|
|
120
|
+
const { state } = this.view;
|
|
121
|
+
const { tr } = state;
|
|
122
|
+
tr.insert(targetPos, fromNode);
|
|
123
|
+
const mappedFrom = tr.mapping.map(fromPos, -1);
|
|
124
|
+
tr.delete(mappedFrom, mappedFrom + fromNode.nodeSize);
|
|
125
|
+
this.view.dispatch(tr);
|
|
126
|
+
}
|
|
127
|
+
addFileInfo() {
|
|
128
|
+
this.supplementInfoEl = document.createElement('div');
|
|
129
|
+
this.supplementInfoEl.classList.add('supplement-file-info');
|
|
130
|
+
this.supplementInfoEl.contentEditable = 'false';
|
|
131
|
+
const files = this.props.getFiles();
|
|
132
|
+
const file = files.find((f) => f.id === this.node.attrs.href);
|
|
133
|
+
if (file) {
|
|
134
|
+
const iconElement = document.createElement('span');
|
|
135
|
+
iconElement.classList.add('supplement-file-icon');
|
|
136
|
+
const icon = (0, style_guide_1.getFileIcon)(file.name);
|
|
137
|
+
if (icon) {
|
|
138
|
+
iconElement.innerHTML = (0, server_1.renderToStaticMarkup)(icon);
|
|
139
|
+
}
|
|
140
|
+
this.supplementInfoEl.appendChild(iconElement);
|
|
141
|
+
const fileName = document.createElement('span');
|
|
142
|
+
fileName.classList.add('supplement-file-name');
|
|
143
|
+
fileName.textContent = file.name;
|
|
144
|
+
this.supplementInfoEl.appendChild(fileName);
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
const placeholder = document.createElement('span');
|
|
148
|
+
placeholder.textContent = 'File not found';
|
|
149
|
+
this.supplementInfoEl.appendChild(placeholder);
|
|
150
|
+
}
|
|
151
|
+
this.dom.appendChild(this.supplementInfoEl);
|
|
152
|
+
}
|
|
153
|
+
refreshFileInfo() {
|
|
154
|
+
this.supplementInfoEl.remove();
|
|
155
|
+
this.addFileInfo();
|
|
156
|
+
}
|
|
157
|
+
addDragIcon() {
|
|
158
|
+
if (this.dragIcon) {
|
|
159
|
+
this.dragIcon.remove();
|
|
160
|
+
this.dragIcon = undefined;
|
|
161
|
+
}
|
|
162
|
+
const dragIcon = document.createElement('div');
|
|
163
|
+
dragIcon.className = 'drag-icon';
|
|
164
|
+
dragIcon.innerHTML = icons_1.draggableIcon;
|
|
165
|
+
dragIcon.draggable = false;
|
|
166
|
+
dragIcon.addEventListener('mousedown', (e) => {
|
|
167
|
+
e.stopPropagation();
|
|
168
|
+
});
|
|
169
|
+
this.dragIcon = dragIcon;
|
|
170
|
+
this.dom.appendChild(dragIcon);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
exports.SupplementView = SupplementView;
|
|
174
|
+
SupplementView.currentDragSupplementId = null;
|
|
175
|
+
exports.default = (0, creators_1.createNodeView)(SupplementView);
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*!
|
|
3
|
+
* © 2025 Atypon Systems LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
const creators_1 = require("./creators");
|
|
19
|
+
const supplement_1 = require("./supplement");
|
|
20
|
+
exports.default = (0, creators_1.createEditableNodeView)(supplement_1.SupplementView);
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*!
|
|
3
|
+
* © 2025 Atypon Systems LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
18
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
19
|
+
};
|
|
20
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
+
exports.SupplementsView = void 0;
|
|
22
|
+
const icons_1 = require("../icons");
|
|
23
|
+
const block_view_1 = __importDefault(require("./block_view"));
|
|
24
|
+
const creators_1 = require("./creators");
|
|
25
|
+
class SupplementsView extends block_view_1.default {
|
|
26
|
+
constructor() {
|
|
27
|
+
super(...arguments);
|
|
28
|
+
this.collapsed = false;
|
|
29
|
+
this.ignoreMutation = () => true;
|
|
30
|
+
this.createElement = () => {
|
|
31
|
+
this.toggleButton = document.createElement('button');
|
|
32
|
+
this.toggleButton.classList.add('supplements-toggle-btn', 'button-reset');
|
|
33
|
+
this.toggleButton.innerHTML = icons_1.arrowUp;
|
|
34
|
+
this.toggleButton.onclick = () => {
|
|
35
|
+
this.collapsed = !this.collapsed;
|
|
36
|
+
this.toggleContent();
|
|
37
|
+
this.toggleButton?.classList.toggle('collapsed', this.collapsed);
|
|
38
|
+
};
|
|
39
|
+
this.contentDOM = document.createElement('div');
|
|
40
|
+
this.contentDOM.classList.add('supplements-content');
|
|
41
|
+
this.contentDOM.classList.add('block');
|
|
42
|
+
this.dom.appendChild(this.toggleButton);
|
|
43
|
+
this.dom.setAttribute('id', this.node.attrs.id);
|
|
44
|
+
this.dom.appendChild(this.contentDOM);
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
toggleContent() {
|
|
48
|
+
const supplementItems = this.contentDOM?.querySelectorAll('.supplement-item');
|
|
49
|
+
supplementItems?.forEach((item) => {
|
|
50
|
+
const element = item;
|
|
51
|
+
element.style.display = this.collapsed ? 'none' : '';
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
exports.SupplementsView = SupplementsView;
|
|
56
|
+
exports.default = (0, creators_1.createNodeView)(SupplementsView);
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*!
|
|
3
|
+
* © 2025 Atypon Systems LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
const creators_1 = require("./creators");
|
|
19
|
+
const editable_block_1 = require("./editable_block");
|
|
20
|
+
const supplements_1 = require("./supplements");
|
|
21
|
+
exports.default = (0, creators_1.createEditableNodeView)((0, editable_block_1.EditableBlock)(supplements_1.SupplementsView));
|
package/dist/es/commands.js
CHANGED
|
@@ -23,7 +23,7 @@ import { addColumnAfter, addColumnBefore, addRow, selectedRect, } from 'prosemir
|
|
|
23
23
|
import { findWrapping, liftTarget, ReplaceAroundStep, ReplaceStep, } from 'prosemirror-transform';
|
|
24
24
|
import { findChildrenByType, findParentNodeOfType, findParentNodeOfTypeClosestToPos, flatten, hasParentNodeOfType, } from 'prosemirror-utils';
|
|
25
25
|
import { getCommentKey, getCommentRange } from './lib/comments';
|
|
26
|
-
import { findAbstractsNode, findBackmatter, findBibliographySection, findBody, findFootnotesSection, insertAttachmentsNode, insertAwardsNode, insertFootnotesSection,
|
|
26
|
+
import { findAbstractsNode, findBackmatter, findBibliographySection, findBody, findFootnotesSection, insertAttachmentsNode, insertAwardsNode, insertFootnotesSection, upsertSupplementsSection, } from './lib/doc';
|
|
27
27
|
import { createFootnote, findFootnotesContainerNode, getFootnotesElementState, } from './lib/footnotes';
|
|
28
28
|
import { findWordBoundaries, isNodeOfType, nearestAncestor, } from './lib/helpers';
|
|
29
29
|
import { templateAllows } from './lib/template';
|
|
@@ -281,18 +281,21 @@ export const insertTable = (config, state, dispatch) => {
|
|
|
281
281
|
dispatch && dispatch(tr);
|
|
282
282
|
return true;
|
|
283
283
|
};
|
|
284
|
-
export const insertSupplement = (file,
|
|
284
|
+
export const insertSupplement = (file, view) => {
|
|
285
285
|
const supplement = schema.nodes.supplement.createAndFill({
|
|
286
286
|
id: generateNodeID(schema.nodes.supplement),
|
|
287
287
|
href: file.id,
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
}
|
|
288
|
+
}, [
|
|
289
|
+
schema.nodes.figcaption.create({}, [
|
|
290
|
+
schema.nodes.caption_title.create(),
|
|
291
|
+
schema.nodes.caption.create(),
|
|
292
|
+
]),
|
|
293
|
+
]);
|
|
294
|
+
const tr = view.state.tr;
|
|
295
|
+
const { pos } = upsertSupplementsSection(tr, supplement);
|
|
296
|
+
tr.setSelection(NodeSelection.create(tr.doc, pos));
|
|
297
|
+
view.focus();
|
|
298
|
+
view.dispatch(tr.scrollIntoView());
|
|
296
299
|
return true;
|
|
297
300
|
};
|
|
298
301
|
export const insertAttachment = (file, state, type, dispatch) => {
|
|
@@ -42,6 +42,8 @@ import sectionLabel from '../views/section_label';
|
|
|
42
42
|
import sectionTitle from '../views/section_title_editable';
|
|
43
43
|
import subtitle from '../views/subtitle_editable';
|
|
44
44
|
import subtitles from '../views/subtitles_editable';
|
|
45
|
+
import supplement from '../views/supplement_editable';
|
|
46
|
+
import supplements from '../views/supplements_editable';
|
|
45
47
|
import tableCell from '../views/table_cell';
|
|
46
48
|
import tableElement from '../views/table_element_editable';
|
|
47
49
|
import tableElementFooter from '../views/table_element_footer';
|
|
@@ -91,7 +93,8 @@ export default (props, dispatch) => {
|
|
|
91
93
|
table_header: tableCell(props),
|
|
92
94
|
table_element_footer: tableElementFooter(props),
|
|
93
95
|
comments: empty('comments'),
|
|
94
|
-
supplements:
|
|
96
|
+
supplements: supplements(props, dispatch),
|
|
97
|
+
supplement: supplement(props, dispatch),
|
|
95
98
|
author_notes: authorNotes(props, dispatch),
|
|
96
99
|
awards: awards(props, dispatch),
|
|
97
100
|
award: award(props, dispatch),
|
package/dist/es/lib/doc.js
CHANGED
|
@@ -15,14 +15,16 @@ export const insertAwardsNode = (tr) => {
|
|
|
15
15
|
pos,
|
|
16
16
|
};
|
|
17
17
|
};
|
|
18
|
-
export const
|
|
18
|
+
export const upsertSupplementsSection = (tr, supplement) => {
|
|
19
19
|
const doc = tr.doc;
|
|
20
20
|
const supplements = findChildrenByType(doc, schema.nodes.supplements)[0];
|
|
21
21
|
if (supplements) {
|
|
22
|
-
|
|
22
|
+
const pos = supplements.pos + supplements.node.nodeSize - 1;
|
|
23
|
+
tr.insert(pos, supplement);
|
|
24
|
+
return { node: supplements.node, pos };
|
|
23
25
|
}
|
|
24
26
|
const pos = findInsertionPosition(schema.nodes.supplements, doc);
|
|
25
|
-
const node = schema.nodes.supplements.createAndFill();
|
|
27
|
+
const node = schema.nodes.supplements.createAndFill({ id: generateNodeID(schema.nodes.supplements) }, [supplement]);
|
|
26
28
|
tr.insert(pos, node);
|
|
27
29
|
return {
|
|
28
30
|
node,
|
package/dist/es/lib/utils.js
CHANGED
|
@@ -161,6 +161,10 @@ export const findInsertionPosition = (type, doc) => {
|
|
|
161
161
|
insertPos = offset;
|
|
162
162
|
}
|
|
163
163
|
});
|
|
164
|
+
if (insertPos === 0 &&
|
|
165
|
+
doc.canReplaceWith(doc.childCount, doc.childCount, type)) {
|
|
166
|
+
insertPos = doc.content.size;
|
|
167
|
+
}
|
|
164
168
|
return insertPos;
|
|
165
169
|
};
|
|
166
170
|
export const filterBlockNodes = (fragment, predicate) => {
|
|
@@ -82,6 +82,9 @@ export default () => new Plugin({
|
|
|
82
82
|
if (findParentNodeOfTypeClosestToPos($pos, schema.nodes.box_element)) {
|
|
83
83
|
placeholderText = 'Optional box title...';
|
|
84
84
|
}
|
|
85
|
+
if (findParentNodeOfTypeClosestToPos($pos, schema.nodes.supplements)) {
|
|
86
|
+
placeholderText = 'Supplements';
|
|
87
|
+
}
|
|
85
88
|
decorations.push(Decoration.widget(pos + 1, placeholderWidget(placeholderText)));
|
|
86
89
|
}
|
|
87
90
|
else if (node.type === node.type.schema.nodes.trans_abstract) {
|
package/dist/es/versions.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const VERSION = '3.6.
|
|
1
|
+
export const VERSION = '3.6.11';
|
|
2
2
|
export const MATHJAX_VERSION = '3.2.2';
|
|
@@ -39,6 +39,7 @@ export const EditableBlock = (Base) => {
|
|
|
39
39
|
const nodeType = this.node.type;
|
|
40
40
|
if (nodeType === schema.nodes.hero_image ||
|
|
41
41
|
nodeType === schema.nodes.subtitles ||
|
|
42
|
+
nodeType === schema.nodes.supplements ||
|
|
42
43
|
hasParent($pos, [
|
|
43
44
|
schema.nodes.keywords,
|
|
44
45
|
schema.nodes.bibliography_section,
|
|
@@ -26,6 +26,7 @@ export class SectionTitleView extends BlockView {
|
|
|
26
26
|
schema.nodes.bibliography_section,
|
|
27
27
|
schema.nodes.footnotes_section,
|
|
28
28
|
schema.nodes.graphical_abstract_section,
|
|
29
|
+
schema.nodes.supplements,
|
|
29
30
|
];
|
|
30
31
|
this.createElement = () => {
|
|
31
32
|
this.contentDOM = document.createElement(this.elementType);
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* © 2025 Atypon Systems LLC
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
import { getFileIcon } from '@manuscripts/style-guide';
|
|
17
|
+
import { renderToStaticMarkup } from 'react-dom/server';
|
|
18
|
+
import { draggableIcon } from '../icons';
|
|
19
|
+
import { findNodeByID } from '../lib/doc';
|
|
20
|
+
import { BaseNodeView } from './base_node_view';
|
|
21
|
+
import { createNodeView } from './creators';
|
|
22
|
+
export class SupplementView extends BaseNodeView {
|
|
23
|
+
constructor() {
|
|
24
|
+
super(...arguments);
|
|
25
|
+
this.ignoreMutation = () => true;
|
|
26
|
+
this.createElement = () => {
|
|
27
|
+
this.dom = document.createElement('div');
|
|
28
|
+
this.dom.classList.add('supplement-item');
|
|
29
|
+
this.dom.classList.add('block');
|
|
30
|
+
this.dom.setAttribute('id', this.node.attrs.id);
|
|
31
|
+
this.dom.setAttribute('href', this.node.attrs.href);
|
|
32
|
+
this.dom.draggable = true;
|
|
33
|
+
this.contentDOM = document.createElement('div');
|
|
34
|
+
this.contentDOM.classList.add('supplement-caption');
|
|
35
|
+
this.dom.appendChild(this.contentDOM);
|
|
36
|
+
this.addFileInfo();
|
|
37
|
+
this.addDragIcon();
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
initialise() {
|
|
41
|
+
this.createElement();
|
|
42
|
+
this.updateContents();
|
|
43
|
+
this.setupDragAndDrop();
|
|
44
|
+
}
|
|
45
|
+
updateContents() {
|
|
46
|
+
super.updateContents();
|
|
47
|
+
this.refreshFileInfo();
|
|
48
|
+
}
|
|
49
|
+
getDropSide(element, clientY) {
|
|
50
|
+
const { top, bottom } = element.getBoundingClientRect();
|
|
51
|
+
const middleY = (top + bottom) / 2;
|
|
52
|
+
return clientY > middleY ? 'after' : 'before';
|
|
53
|
+
}
|
|
54
|
+
noActualMove(currentPos, nodeSize, targetPos) {
|
|
55
|
+
return targetPos === currentPos || targetPos === currentPos + nodeSize;
|
|
56
|
+
}
|
|
57
|
+
handleDragStart() {
|
|
58
|
+
const supplementId = this.node.attrs.id;
|
|
59
|
+
SupplementView.currentDragSupplementId = supplementId;
|
|
60
|
+
this.dom.classList.add('dragging');
|
|
61
|
+
}
|
|
62
|
+
setupDragAndDrop() {
|
|
63
|
+
const clearDropClasses = () => {
|
|
64
|
+
this.dom.classList.remove('drop-target-above', 'drop-target-below');
|
|
65
|
+
};
|
|
66
|
+
this.dom.addEventListener('dragstart', () => {
|
|
67
|
+
if (this.node.attrs.id) {
|
|
68
|
+
this.handleDragStart();
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
this.dom.addEventListener('dragend', () => {
|
|
72
|
+
SupplementView.currentDragSupplementId = null;
|
|
73
|
+
this.dom.classList.remove('dragging');
|
|
74
|
+
clearDropClasses();
|
|
75
|
+
});
|
|
76
|
+
this.dom.addEventListener('dragover', (e) => {
|
|
77
|
+
if (SupplementView.currentDragSupplementId) {
|
|
78
|
+
e.preventDefault();
|
|
79
|
+
e.stopPropagation();
|
|
80
|
+
const side = this.getDropSide(this.dom, e.clientY);
|
|
81
|
+
clearDropClasses();
|
|
82
|
+
this.dom.classList.add(side === 'before' ? 'drop-target-above' : 'drop-target-below');
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
this.dom.addEventListener('dragleave', (e) => {
|
|
86
|
+
if (!this.dom.contains(e.relatedTarget)) {
|
|
87
|
+
clearDropClasses();
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
this.dom.addEventListener('drop', (e) => {
|
|
91
|
+
if (!SupplementView.currentDragSupplementId) {
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
e.preventDefault();
|
|
95
|
+
e.stopPropagation();
|
|
96
|
+
const supplementId = SupplementView.currentDragSupplementId;
|
|
97
|
+
if (!supplementId) {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
const { state } = this.view;
|
|
101
|
+
const supplement = findNodeByID(state.doc, supplementId);
|
|
102
|
+
if (!supplement) {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
const toPos = this.getPos();
|
|
106
|
+
const side = this.getDropSide(this.dom, e.clientY);
|
|
107
|
+
const targetPos = side === 'before' ? toPos : toPos + this.node.nodeSize;
|
|
108
|
+
if (this.noActualMove(supplement.pos, supplement.node.nodeSize, targetPos)) {
|
|
109
|
+
clearDropClasses();
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
this.moveSupplement(supplement.pos, supplement.node, targetPos);
|
|
113
|
+
clearDropClasses();
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
moveSupplement(fromPos, fromNode, targetPos) {
|
|
117
|
+
const { state } = this.view;
|
|
118
|
+
const { tr } = state;
|
|
119
|
+
tr.insert(targetPos, fromNode);
|
|
120
|
+
const mappedFrom = tr.mapping.map(fromPos, -1);
|
|
121
|
+
tr.delete(mappedFrom, mappedFrom + fromNode.nodeSize);
|
|
122
|
+
this.view.dispatch(tr);
|
|
123
|
+
}
|
|
124
|
+
addFileInfo() {
|
|
125
|
+
this.supplementInfoEl = document.createElement('div');
|
|
126
|
+
this.supplementInfoEl.classList.add('supplement-file-info');
|
|
127
|
+
this.supplementInfoEl.contentEditable = 'false';
|
|
128
|
+
const files = this.props.getFiles();
|
|
129
|
+
const file = files.find((f) => f.id === this.node.attrs.href);
|
|
130
|
+
if (file) {
|
|
131
|
+
const iconElement = document.createElement('span');
|
|
132
|
+
iconElement.classList.add('supplement-file-icon');
|
|
133
|
+
const icon = getFileIcon(file.name);
|
|
134
|
+
if (icon) {
|
|
135
|
+
iconElement.innerHTML = renderToStaticMarkup(icon);
|
|
136
|
+
}
|
|
137
|
+
this.supplementInfoEl.appendChild(iconElement);
|
|
138
|
+
const fileName = document.createElement('span');
|
|
139
|
+
fileName.classList.add('supplement-file-name');
|
|
140
|
+
fileName.textContent = file.name;
|
|
141
|
+
this.supplementInfoEl.appendChild(fileName);
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
const placeholder = document.createElement('span');
|
|
145
|
+
placeholder.textContent = 'File not found';
|
|
146
|
+
this.supplementInfoEl.appendChild(placeholder);
|
|
147
|
+
}
|
|
148
|
+
this.dom.appendChild(this.supplementInfoEl);
|
|
149
|
+
}
|
|
150
|
+
refreshFileInfo() {
|
|
151
|
+
this.supplementInfoEl.remove();
|
|
152
|
+
this.addFileInfo();
|
|
153
|
+
}
|
|
154
|
+
addDragIcon() {
|
|
155
|
+
if (this.dragIcon) {
|
|
156
|
+
this.dragIcon.remove();
|
|
157
|
+
this.dragIcon = undefined;
|
|
158
|
+
}
|
|
159
|
+
const dragIcon = document.createElement('div');
|
|
160
|
+
dragIcon.className = 'drag-icon';
|
|
161
|
+
dragIcon.innerHTML = draggableIcon;
|
|
162
|
+
dragIcon.draggable = false;
|
|
163
|
+
dragIcon.addEventListener('mousedown', (e) => {
|
|
164
|
+
e.stopPropagation();
|
|
165
|
+
});
|
|
166
|
+
this.dragIcon = dragIcon;
|
|
167
|
+
this.dom.appendChild(dragIcon);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
SupplementView.currentDragSupplementId = null;
|
|
171
|
+
export default createNodeView(SupplementView);
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* © 2025 Atypon Systems LLC
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
import { createEditableNodeView } from './creators';
|
|
17
|
+
import { SupplementView } from './supplement';
|
|
18
|
+
export default createEditableNodeView(SupplementView);
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* © 2025 Atypon Systems LLC
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
import { arrowUp } from '../icons';
|
|
17
|
+
import BlockView from './block_view';
|
|
18
|
+
import { createNodeView } from './creators';
|
|
19
|
+
export class SupplementsView extends BlockView {
|
|
20
|
+
constructor() {
|
|
21
|
+
super(...arguments);
|
|
22
|
+
this.collapsed = false;
|
|
23
|
+
this.ignoreMutation = () => true;
|
|
24
|
+
this.createElement = () => {
|
|
25
|
+
this.toggleButton = document.createElement('button');
|
|
26
|
+
this.toggleButton.classList.add('supplements-toggle-btn', 'button-reset');
|
|
27
|
+
this.toggleButton.innerHTML = arrowUp;
|
|
28
|
+
this.toggleButton.onclick = () => {
|
|
29
|
+
this.collapsed = !this.collapsed;
|
|
30
|
+
this.toggleContent();
|
|
31
|
+
this.toggleButton?.classList.toggle('collapsed', this.collapsed);
|
|
32
|
+
};
|
|
33
|
+
this.contentDOM = document.createElement('div');
|
|
34
|
+
this.contentDOM.classList.add('supplements-content');
|
|
35
|
+
this.contentDOM.classList.add('block');
|
|
36
|
+
this.dom.appendChild(this.toggleButton);
|
|
37
|
+
this.dom.setAttribute('id', this.node.attrs.id);
|
|
38
|
+
this.dom.appendChild(this.contentDOM);
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
toggleContent() {
|
|
42
|
+
const supplementItems = this.contentDOM?.querySelectorAll('.supplement-item');
|
|
43
|
+
supplementItems?.forEach((item) => {
|
|
44
|
+
const element = item;
|
|
45
|
+
element.style.display = this.collapsed ? 'none' : '';
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
export default createNodeView(SupplementsView);
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* © 2025 Atypon Systems LLC
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
import { createEditableNodeView } from './creators';
|
|
17
|
+
import { EditableBlock } from './editable_block';
|
|
18
|
+
import { SupplementsView } from './supplements';
|
|
19
|
+
export default createEditableNodeView(EditableBlock(SupplementsView));
|
package/dist/types/commands.d.ts
CHANGED
|
@@ -32,7 +32,7 @@ export declare const insertGeneralTableFootnote: (element: [ManuscriptNode, numb
|
|
|
32
32
|
export declare const insertFigure: (file: FileAttachment, state: ManuscriptEditorState, dispatch?: Dispatch) => boolean;
|
|
33
33
|
export declare const insertEmbed: (state: ManuscriptEditorState, dispatch?: Dispatch, attrs?: Attrs) => boolean;
|
|
34
34
|
export declare const insertTable: (config: TableConfig, state: ManuscriptEditorState, dispatch?: Dispatch) => boolean;
|
|
35
|
-
export declare const insertSupplement: (file: FileAttachment,
|
|
35
|
+
export declare const insertSupplement: (file: FileAttachment, view: ManuscriptEditorView) => boolean;
|
|
36
36
|
export declare const insertAttachment: (file: FileAttachment, state: ManuscriptEditorState, type: string, dispatch?: Dispatch) => boolean;
|
|
37
37
|
export declare const insertBlock: (nodeType: ManuscriptNodeType) => (state: ManuscriptEditorState, dispatch?: Dispatch) => boolean;
|
|
38
38
|
export declare const deleteBlock: (typeToDelete: string) => (state: ManuscriptEditorState, dispatch?: Dispatch) => boolean;
|
package/dist/types/lib/doc.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AwardsNode, ManuscriptNode, ManuscriptTransaction, SupplementsNode } from '@manuscripts/transform';
|
|
1
|
+
import { AwardsNode, ManuscriptNode, ManuscriptTransaction, SupplementNode, SupplementsNode } from '@manuscripts/transform';
|
|
2
2
|
export declare const insertAwardsNode: (tr: ManuscriptTransaction) => {
|
|
3
3
|
node: import("prosemirror-model").Node;
|
|
4
4
|
pos: number;
|
|
@@ -6,7 +6,7 @@ export declare const insertAwardsNode: (tr: ManuscriptTransaction) => {
|
|
|
6
6
|
node: AwardsNode;
|
|
7
7
|
pos: number;
|
|
8
8
|
};
|
|
9
|
-
export declare const
|
|
9
|
+
export declare const upsertSupplementsSection: (tr: ManuscriptTransaction, supplement: SupplementNode) => {
|
|
10
10
|
node: import("prosemirror-model").Node;
|
|
11
11
|
pos: number;
|
|
12
12
|
} | {
|
package/dist/types/versions.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const VERSION = "3.6.
|
|
1
|
+
export declare const VERSION = "3.6.11";
|
|
2
2
|
export declare const MATHJAX_VERSION = "3.2.2";
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* © 2025 Atypon Systems LLC
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
import { SupplementNode } from '@manuscripts/transform';
|
|
17
|
+
import { Trackable } from '../types';
|
|
18
|
+
import { BaseNodeView } from './base_node_view';
|
|
19
|
+
export declare class SupplementView extends BaseNodeView<Trackable<SupplementNode>> {
|
|
20
|
+
private supplementInfoEl;
|
|
21
|
+
private static currentDragSupplementId;
|
|
22
|
+
private dragIcon;
|
|
23
|
+
ignoreMutation: () => boolean;
|
|
24
|
+
initialise(): void;
|
|
25
|
+
createElement: () => void;
|
|
26
|
+
updateContents(): void;
|
|
27
|
+
private getDropSide;
|
|
28
|
+
private noActualMove;
|
|
29
|
+
private handleDragStart;
|
|
30
|
+
private setupDragAndDrop;
|
|
31
|
+
private moveSupplement;
|
|
32
|
+
private addFileInfo;
|
|
33
|
+
private refreshFileInfo;
|
|
34
|
+
private addDragIcon;
|
|
35
|
+
}
|
|
36
|
+
declare const _default: (props: import("../configs/ManuscriptsEditor").EditorProps, dispatch?: import("..").Dispatch) => import("../types").NodeViewCreator<SupplementView>;
|
|
37
|
+
export default _default;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* © 2025 Atypon Systems LLC
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
import { SupplementView } from './supplement';
|
|
17
|
+
declare const _default: (props: import("../configs/ManuscriptsEditor").EditorProps, dispatch?: import("..").Dispatch) => import("../types").NodeViewCreator<SupplementView>;
|
|
18
|
+
export default _default;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* © 2025 Atypon Systems LLC
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
import { SupplementsNode } from '@manuscripts/transform';
|
|
17
|
+
import { Trackable } from '../types';
|
|
18
|
+
import BlockView from './block_view';
|
|
19
|
+
export declare class SupplementsView extends BlockView<Trackable<SupplementsNode>> {
|
|
20
|
+
private collapsed;
|
|
21
|
+
private toggleButton;
|
|
22
|
+
ignoreMutation: () => boolean;
|
|
23
|
+
createElement: () => void;
|
|
24
|
+
private toggleContent;
|
|
25
|
+
}
|
|
26
|
+
declare const _default: (props: import("../configs/ManuscriptsEditor").EditorProps, dispatch?: import("..").Dispatch) => import("../types").NodeViewCreator<SupplementsView>;
|
|
27
|
+
export default _default;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* © 2025 Atypon Systems LLC
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
import { SupplementsView } from './supplements';
|
|
17
|
+
declare const _default: (props: import("../configs/ManuscriptsEditor").EditorProps, dispatch?: import("..").Dispatch) => import("../types").NodeViewCreator<{
|
|
18
|
+
gutterButtons(): HTMLElement[];
|
|
19
|
+
actionGutterButtons(): never[];
|
|
20
|
+
createAddButton(): HTMLAnchorElement | null;
|
|
21
|
+
createEditButton(): HTMLElement | null;
|
|
22
|
+
createMenu: () => import("../lib/context-menu").ContextMenu;
|
|
23
|
+
initialise(): void;
|
|
24
|
+
updateContents(): void;
|
|
25
|
+
handleTrackChanges(): void;
|
|
26
|
+
updateClasses(): void;
|
|
27
|
+
updatePlaceholder(): void;
|
|
28
|
+
createElement(): void;
|
|
29
|
+
createDOM(): void;
|
|
30
|
+
gutter: Record<string, HTMLElement>;
|
|
31
|
+
createGutter(className: string, buttons: HTMLElement[]): void;
|
|
32
|
+
dom: HTMLElement;
|
|
33
|
+
contentDOM?: HTMLElement;
|
|
34
|
+
elementType: string;
|
|
35
|
+
readonly props: import("../configs/ManuscriptsEditor").EditorProps;
|
|
36
|
+
node: import("prosemirror-model").Node;
|
|
37
|
+
readonly view: import("@manuscripts/transform").ManuscriptEditorView;
|
|
38
|
+
readonly getPos: () => number;
|
|
39
|
+
update(newNode: import("@manuscripts/transform").ManuscriptNode): boolean;
|
|
40
|
+
selectNode(): void;
|
|
41
|
+
deselectNode(): void;
|
|
42
|
+
destroy(): void;
|
|
43
|
+
} & SupplementsView>;
|
|
44
|
+
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.6.
|
|
4
|
+
"version": "3.6.11",
|
|
5
5
|
"repository": "github:Atypon-OpenSource/manuscripts-body-editor",
|
|
6
6
|
"license": "Apache-2.0",
|
|
7
7
|
"main": "dist/cjs",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"@manuscripts/json-schema": "2.2.12",
|
|
42
42
|
"@manuscripts/style-guide": "3.3.4",
|
|
43
43
|
"@manuscripts/track-changes-plugin": "2.1.0",
|
|
44
|
-
"@manuscripts/transform": "4.3.
|
|
44
|
+
"@manuscripts/transform": "4.3.6",
|
|
45
45
|
"@popperjs/core": "2.11.8",
|
|
46
46
|
"citeproc": "2.4.63",
|
|
47
47
|
"codemirror": "5.65.19",
|
|
@@ -840,7 +840,9 @@ span.comment-marker {
|
|
|
840
840
|
|
|
841
841
|
.selected-suggestion:not(.block-container):not(.graphical-abstract):not(
|
|
842
842
|
.keywords
|
|
843
|
-
):not(figure):not(figure .equation):not(.inconsistency-highlight)
|
|
843
|
+
):not(figure):not(figure .equation):not(.inconsistency-highlight):not(
|
|
844
|
+
.supplement-item:is([data-track-op='move'])
|
|
845
|
+
),
|
|
844
846
|
.footnote-marker-selected {
|
|
845
847
|
border-width: 2px 0 2px 0 !important;
|
|
846
848
|
border-style: solid !important;
|
|
@@ -1067,13 +1069,19 @@ figure.block:has(.equation.selected-suggestion) {
|
|
|
1067
1069
|
.tracking-visible
|
|
1068
1070
|
.selected-suggestion:is([data-track-op='move'], [data-track-op='structure'])
|
|
1069
1071
|
.block,
|
|
1070
|
-
.block:has(
|
|
1072
|
+
.block:not(.supplements-content):has(
|
|
1071
1073
|
figure.selected-suggestion,
|
|
1072
1074
|
[data-track-op='move'][data-track-status='pending']
|
|
1073
1075
|
) {
|
|
1074
1076
|
box-shadow: inset 3px 0 0 var(--updated-border-color);
|
|
1075
1077
|
}
|
|
1076
1078
|
|
|
1079
|
+
.supplements-content.block:has(
|
|
1080
|
+
[data-track-op='move'][data-track-status='pending']
|
|
1081
|
+
) {
|
|
1082
|
+
border-left: 3px solid var(--updated-border-color) !important;
|
|
1083
|
+
}
|
|
1084
|
+
|
|
1077
1085
|
.tracking-visible
|
|
1078
1086
|
.selected-suggestion[data-track-op='set_attrs']
|
|
1079
1087
|
.block:not(.trans-abstract),
|
|
@@ -1693,7 +1701,7 @@ th:hover > .table-context-menu-button,
|
|
|
1693
1701
|
left: 93%;
|
|
1694
1702
|
}
|
|
1695
1703
|
|
|
1696
|
-
.block-hero_image {
|
|
1704
|
+
.block-hero_image, .block-supplements {
|
|
1697
1705
|
margin-bottom: 30px;
|
|
1698
1706
|
}
|
|
1699
1707
|
|
|
@@ -1703,6 +1711,7 @@ th:hover > .table-context-menu-button,
|
|
|
1703
1711
|
border-radius: 4px;
|
|
1704
1712
|
background: #ffffff;
|
|
1705
1713
|
padding: 0 !important;
|
|
1714
|
+
width: 100%;
|
|
1706
1715
|
}
|
|
1707
1716
|
|
|
1708
1717
|
.ProseMirror div.backmatter:has(+ .block-container.block-hero_image)::after {
|
|
@@ -1744,7 +1753,8 @@ th:hover > .table-context-menu-button,
|
|
|
1744
1753
|
|
|
1745
1754
|
.ProseMirror .block-image_element .block:focus-visible,
|
|
1746
1755
|
.ProseMirror .block-figure_element .block:focus-visible,
|
|
1747
|
-
.ProseMirror .block-embed .block:focus-visible
|
|
1756
|
+
.ProseMirror .block-embed .block:focus-visible,
|
|
1757
|
+
.ProseMirror .supplement-caption:focus-visible {
|
|
1748
1758
|
outline: none;
|
|
1749
1759
|
}
|
|
1750
1760
|
|
package/styles/Editor.css
CHANGED
|
@@ -1134,3 +1134,162 @@
|
|
|
1134
1134
|
.highlight {
|
|
1135
1135
|
background-color: #ffeebf !important;
|
|
1136
1136
|
}
|
|
1137
|
+
|
|
1138
|
+
.ProseMirror .supplement-item {
|
|
1139
|
+
position: relative;
|
|
1140
|
+
padding: 12px 24px;
|
|
1141
|
+
border-bottom: 1px solid #e2e2e2;
|
|
1142
|
+
}
|
|
1143
|
+
|
|
1144
|
+
.ProseMirror .supplement-item:last-child {
|
|
1145
|
+
border-bottom: none;
|
|
1146
|
+
}
|
|
1147
|
+
|
|
1148
|
+
.ProseMirror .supplement-item figcaption {
|
|
1149
|
+
text-align: left;
|
|
1150
|
+
margin-top: 0;
|
|
1151
|
+
}
|
|
1152
|
+
|
|
1153
|
+
.ProseMirror .supplement-item .caption-title.empty-node::before {
|
|
1154
|
+
content: 'Insert caption title...';
|
|
1155
|
+
color: #c9c9c9;
|
|
1156
|
+
font-style: italic;
|
|
1157
|
+
}
|
|
1158
|
+
|
|
1159
|
+
.ProseMirror .supplement-item .caption-description.empty-node::before {
|
|
1160
|
+
content: 'Insert caption...';
|
|
1161
|
+
color: #c9c9c9;
|
|
1162
|
+
font-style: italic;
|
|
1163
|
+
}
|
|
1164
|
+
|
|
1165
|
+
.ProseMirror .supplement-file-info {
|
|
1166
|
+
display: flex;
|
|
1167
|
+
align-items: center;
|
|
1168
|
+
margin-top: 8px;
|
|
1169
|
+
gap: 4px;
|
|
1170
|
+
}
|
|
1171
|
+
|
|
1172
|
+
.ProseMirror .supplement-file-icon {
|
|
1173
|
+
display: flex;
|
|
1174
|
+
align-items: center;
|
|
1175
|
+
width: 14px;
|
|
1176
|
+
height: 16px;
|
|
1177
|
+
}
|
|
1178
|
+
|
|
1179
|
+
.ProseMirror .supplement-file-name {
|
|
1180
|
+
font-size: 14px;
|
|
1181
|
+
}
|
|
1182
|
+
|
|
1183
|
+
|
|
1184
|
+
.ProseMirror .supplements-toggle-btn {
|
|
1185
|
+
background: none;
|
|
1186
|
+
border: none;
|
|
1187
|
+
cursor: pointer;
|
|
1188
|
+
padding: 0;
|
|
1189
|
+
display: flex;
|
|
1190
|
+
align-items: center;
|
|
1191
|
+
justify-content: center;
|
|
1192
|
+
transition: opacity 0.2s ease;
|
|
1193
|
+
position: absolute;
|
|
1194
|
+
top: 16px;
|
|
1195
|
+
right: 65px;
|
|
1196
|
+
z-index: 10;
|
|
1197
|
+
}
|
|
1198
|
+
|
|
1199
|
+
|
|
1200
|
+
.ProseMirror .supplements-toggle-btn svg {
|
|
1201
|
+
width: 16px;
|
|
1202
|
+
height: 9px;
|
|
1203
|
+
}
|
|
1204
|
+
|
|
1205
|
+
.ProseMirror .supplements-toggle-btn.collapsed svg {
|
|
1206
|
+
transform: rotate(180deg);
|
|
1207
|
+
}
|
|
1208
|
+
|
|
1209
|
+
|
|
1210
|
+
.ProseMirror .supplements-content {
|
|
1211
|
+
border: 1px solid #c9c9c9;
|
|
1212
|
+
border-radius: 4px;
|
|
1213
|
+
background: white;
|
|
1214
|
+
padding: 0 !important;
|
|
1215
|
+
width: 100%;
|
|
1216
|
+
}
|
|
1217
|
+
|
|
1218
|
+
/* Make section title look like a horizontal panel header */
|
|
1219
|
+
.ProseMirror .supplements-content .block-section_title {
|
|
1220
|
+
border-top: 1px solid #c9c9c9;
|
|
1221
|
+
border-bottom: 1px solid #c9c9c9;
|
|
1222
|
+
display: block !important;
|
|
1223
|
+
}
|
|
1224
|
+
|
|
1225
|
+
.ProseMirror .supplements-content .block-section_title .block-gutter {
|
|
1226
|
+
display: none;
|
|
1227
|
+
}
|
|
1228
|
+
|
|
1229
|
+
.ProseMirror .supplements-content .block-section_title .action-gutter {
|
|
1230
|
+
display: none;
|
|
1231
|
+
}
|
|
1232
|
+
|
|
1233
|
+
.ProseMirror .supplements-content .block-section_title h1 {
|
|
1234
|
+
background-color: #f2f2f2;
|
|
1235
|
+
padding: 8px 12px !important;
|
|
1236
|
+
font-size: 14px;
|
|
1237
|
+
display: flex;
|
|
1238
|
+
margin-top: -1px;
|
|
1239
|
+
color: #6e6e6e !important;
|
|
1240
|
+
}
|
|
1241
|
+
|
|
1242
|
+
.ProseMirror .supplements-content .block-section_title h1.empty-node span {
|
|
1243
|
+
color: #6e6e6e !important;
|
|
1244
|
+
font-style: normal;
|
|
1245
|
+
}
|
|
1246
|
+
|
|
1247
|
+
/* Horizontal line before supplements block */
|
|
1248
|
+
.ProseMirror div.backmatter:has(+ .block-container.block-supplements)::after {
|
|
1249
|
+
content: '';
|
|
1250
|
+
display: block;
|
|
1251
|
+
border-bottom: 1px solid #e2e2e2;
|
|
1252
|
+
margin: 0 35pt 32px 35pt;
|
|
1253
|
+
}
|
|
1254
|
+
|
|
1255
|
+
.ProseMirror .supplement-item.drop-target-above,
|
|
1256
|
+
.ProseMirror .supplement-item.drop-target-below {
|
|
1257
|
+
border: 2px dotted #20aedf !important;
|
|
1258
|
+
}
|
|
1259
|
+
|
|
1260
|
+
.ProseMirror .supplement-item.dragging {
|
|
1261
|
+
background-color: #F2F2F2 !important;
|
|
1262
|
+
opacity: 0.3;
|
|
1263
|
+
z-index: 1000;
|
|
1264
|
+
}
|
|
1265
|
+
|
|
1266
|
+
.ProseMirror .supplement-item:hover {
|
|
1267
|
+
background-color: #F2F2F2 !important;
|
|
1268
|
+
cursor: move;
|
|
1269
|
+
}
|
|
1270
|
+
|
|
1271
|
+
.ProseMirror .supplement-item:hover figcaption {
|
|
1272
|
+
background-color: #F2F2F2 !important;
|
|
1273
|
+
}
|
|
1274
|
+
|
|
1275
|
+
.ProseMirror .supplement-item .drag-icon {
|
|
1276
|
+
position: absolute;
|
|
1277
|
+
top: 50%;
|
|
1278
|
+
left: 0;
|
|
1279
|
+
transform: translateY(-50%);
|
|
1280
|
+
width: 16px;
|
|
1281
|
+
height: 16px;
|
|
1282
|
+
cursor: grab;
|
|
1283
|
+
opacity: 0;
|
|
1284
|
+
transition: opacity 0.2s;
|
|
1285
|
+
z-index: 5;
|
|
1286
|
+
pointer-events: auto;
|
|
1287
|
+
}
|
|
1288
|
+
|
|
1289
|
+
.ProseMirror .supplement-item:hover .drag-icon {
|
|
1290
|
+
opacity: 1;
|
|
1291
|
+
}
|
|
1292
|
+
|
|
1293
|
+
.ProseMirror .supplement-item .drag-icon:active {
|
|
1294
|
+
cursor: grabbing;
|
|
1295
|
+
}
|