@manuscripts/body-editor 1.9.4 → 1.9.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/plugins/footnotes/footnotes-utils.js +2 -2
- package/dist/cjs/plugins/footnotes/index.js +31 -39
- package/dist/es/plugins/footnotes/footnotes-utils.js +2 -2
- package/dist/es/plugins/footnotes/index.js +32 -40
- package/dist/types/plugins/footnotes/footnotes-utils.d.ts +1 -1
- package/package.json +2 -2
- package/styles/Editor.css +9 -13
|
@@ -99,9 +99,9 @@ const updateTableInlineFootnoteLabels = (tr, table) => {
|
|
|
99
99
|
return tr;
|
|
100
100
|
};
|
|
101
101
|
exports.updateTableInlineFootnoteLabels = updateTableInlineFootnoteLabels;
|
|
102
|
-
const getInlineFootnotes = (id,
|
|
102
|
+
const getInlineFootnotes = (id, targetNode) => {
|
|
103
103
|
const inlineFootnotes = [];
|
|
104
|
-
|
|
104
|
+
targetNode.descendants((node, pos) => {
|
|
105
105
|
var _a;
|
|
106
106
|
if (node.type === transform_1.schema.nodes.inline_footnote) {
|
|
107
107
|
const footnote = node;
|
|
@@ -73,11 +73,20 @@ const uncitedFootnoteWidget = () => () => {
|
|
|
73
73
|
return element;
|
|
74
74
|
};
|
|
75
75
|
exports.uncitedFootnoteWidget = uncitedFootnoteWidget;
|
|
76
|
-
const deleteFootnoteWidget = (node, props,
|
|
76
|
+
const deleteFootnoteWidget = (node, props, id, tableElement) => (view, getPos) => {
|
|
77
77
|
const deleteBtn = document.createElement('span');
|
|
78
78
|
deleteBtn.className = 'delete-icon';
|
|
79
79
|
deleteBtn.innerHTML = assets_1.deleteIcon;
|
|
80
|
-
|
|
80
|
+
const parentType = tableElement ? 'table ' : '';
|
|
81
|
+
const footnote = {
|
|
82
|
+
type: node.type === transform_1.schema.nodes.footnote
|
|
83
|
+
? `${parentType}footnote`
|
|
84
|
+
: 'table general note',
|
|
85
|
+
message: node.type === transform_1.schema.nodes.footnote
|
|
86
|
+
? `This action will entirely remove the ${parentType}footnote from the list because it will no longer be used.`
|
|
87
|
+
: 'This action will entirely remove the table general note.',
|
|
88
|
+
};
|
|
89
|
+
deleteBtn.addEventListener('mousedown', () => {
|
|
81
90
|
const handleDelete = () => {
|
|
82
91
|
let tr = view.state.tr;
|
|
83
92
|
const pos = getPos();
|
|
@@ -95,7 +104,8 @@ const deleteFootnoteWidget = (node, props, footnoteType, footnoteMessage, id, ta
|
|
|
95
104
|
}
|
|
96
105
|
}
|
|
97
106
|
if (node.type === transform_1.schema.nodes.footnote && pos) {
|
|
98
|
-
const
|
|
107
|
+
const targetNode = tableElement ? tableElement.node : view.state.doc;
|
|
108
|
+
const inlineFootnotes = (0, footnotes_utils_1.getInlineFootnotes)(id, targetNode);
|
|
99
109
|
const nodeWithPos = (0, prosemirror_utils_1.findParentNodeClosestToPos)(tr.doc.resolve(pos), (node) => node.type === transform_1.schema.nodes.footnote);
|
|
100
110
|
if (nodeWithPos) {
|
|
101
111
|
const { pos: fnPos, node: fnNode } = nodeWithPos;
|
|
@@ -104,13 +114,13 @@ const deleteFootnoteWidget = (node, props, footnoteType, footnoteMessage, id, ta
|
|
|
104
114
|
if (inlineFootnotes) {
|
|
105
115
|
tr = view.state.tr;
|
|
106
116
|
inlineFootnotes.forEach((footnote) => {
|
|
107
|
-
const pos = footnote.pos + tableElement.pos;
|
|
117
|
+
const pos = footnote.pos + (tableElement ? tableElement.pos + 1 : 0);
|
|
108
118
|
if (footnote.node.attrs.rids.length > 1) {
|
|
109
119
|
const updatedRids = footnote.node.attrs.rids.filter((rid) => rid !== id);
|
|
110
120
|
tr.setNodeMarkup(tr.mapping.map(pos + 1), undefined, Object.assign(Object.assign({}, node.attrs), { rids: updatedRids }));
|
|
111
121
|
}
|
|
112
122
|
else {
|
|
113
|
-
tr.delete(tr.mapping.map(pos
|
|
123
|
+
tr.delete(tr.mapping.map(pos), tr.mapping.map(pos + footnote.node.nodeSize));
|
|
114
124
|
}
|
|
115
125
|
});
|
|
116
126
|
}
|
|
@@ -118,8 +128,8 @@ const deleteFootnoteWidget = (node, props, footnoteType, footnoteMessage, id, ta
|
|
|
118
128
|
view.dispatch(tr);
|
|
119
129
|
};
|
|
120
130
|
const componentProps = {
|
|
121
|
-
footnoteType:
|
|
122
|
-
footnoteMessage:
|
|
131
|
+
footnoteType: footnote.type,
|
|
132
|
+
footnoteMessage: footnote.message,
|
|
123
133
|
handleDelete: handleDelete,
|
|
124
134
|
};
|
|
125
135
|
(0, ReactSubView_1.default)(Object.assign(Object.assign({}, props), { dispatch: view.dispatch }), DeleteFootnoteDialog_1.DeleteFootnoteDialog, componentProps, node, () => getPos(), view);
|
|
@@ -158,19 +168,30 @@ exports.default = (props) => {
|
|
|
158
168
|
props: {
|
|
159
169
|
decorations: (state) => {
|
|
160
170
|
const decorations = [];
|
|
161
|
-
const
|
|
171
|
+
const tableElementFooter = (0, prosemirror_utils_1.findParentNodeOfType)(transform_1.schema.nodes.table_element_footer)(state.selection);
|
|
162
172
|
const tableElement = (0, prosemirror_utils_1.findParentNodeOfType)(transform_1.schema.nodes.table_element)(state.selection);
|
|
163
|
-
|
|
173
|
+
const footnote = (0, prosemirror_utils_1.findParentNodeOfType)(transform_1.schema.nodes.footnote)(state.selection);
|
|
174
|
+
let targetNode;
|
|
175
|
+
if (footnote) {
|
|
176
|
+
targetNode = footnote;
|
|
177
|
+
}
|
|
178
|
+
else if (tableElementFooter) {
|
|
179
|
+
targetNode = tableElementFooter;
|
|
180
|
+
}
|
|
181
|
+
const can = props.getCapabilities();
|
|
182
|
+
if (targetNode && can.editArticle) {
|
|
164
183
|
const parent = (0, utils_1.findParentNodeWithIdValue)(state.selection);
|
|
165
184
|
if (parent) {
|
|
166
185
|
decorations.push(prosemirror_view_1.Decoration.node(parent.pos, parent.pos + parent.node.nodeSize, {
|
|
167
186
|
class: 'footnote-selected',
|
|
168
187
|
}));
|
|
188
|
+
decorations.push(prosemirror_view_1.Decoration.widget(targetNode.pos + (footnote ? 1 : 2), deleteFootnoteWidget(targetNode.node, props, targetNode.node.attrs.id, tableElement), {
|
|
189
|
+
key: targetNode.node.attrs.id,
|
|
190
|
+
}));
|
|
169
191
|
}
|
|
170
192
|
}
|
|
171
193
|
const { labels } = exports.footnotesKey.getState(state);
|
|
172
194
|
let tableInlineFootnoteIds = undefined;
|
|
173
|
-
const can = props.getCapabilities();
|
|
174
195
|
state.doc.descendants((node, pos, parent) => {
|
|
175
196
|
var _a;
|
|
176
197
|
if ((0, transform_1.isFootnoteNode)(node)) {
|
|
@@ -191,35 +212,6 @@ exports.default = (props) => {
|
|
|
191
212
|
decorations.push(prosemirror_view_1.Decoration.widget(pos + node.nodeSize - 1, (0, exports.uncitedFootnoteWidget)()));
|
|
192
213
|
}
|
|
193
214
|
}
|
|
194
|
-
if (can.editArticle) {
|
|
195
|
-
if (tableElement) {
|
|
196
|
-
const footnote = (() => {
|
|
197
|
-
switch (node.type) {
|
|
198
|
-
case transform_1.schema.nodes.footnote:
|
|
199
|
-
return {
|
|
200
|
-
type: 'table footnote',
|
|
201
|
-
message: 'This action will entirely remove the table footnote from the list because it will no longer be used.',
|
|
202
|
-
};
|
|
203
|
-
default:
|
|
204
|
-
return {
|
|
205
|
-
type: 'table general note',
|
|
206
|
-
message: 'This action will entirely remove the table general note.',
|
|
207
|
-
};
|
|
208
|
-
}
|
|
209
|
-
})();
|
|
210
|
-
if (node.type === transform_1.schema.nodes.footnote) {
|
|
211
|
-
decorations.push(prosemirror_view_1.Decoration.widget(pos + 2, deleteFootnoteWidget(node, props, footnote.type, footnote.message, node.attrs.id, tableElement), {
|
|
212
|
-
key: node.attrs.id,
|
|
213
|
-
}));
|
|
214
|
-
}
|
|
215
|
-
else if (node.type === transform_1.schema.nodes.paragraph &&
|
|
216
|
-
(parent === null || parent === void 0 ? void 0 : parent.type) === transform_1.schema.nodes.table_element_footer) {
|
|
217
|
-
decorations.push(prosemirror_view_1.Decoration.widget(pos + 1, deleteFootnoteWidget(parent, props, footnote.type, footnote.message, parent.attrs.id, tableElement), {
|
|
218
|
-
key: parent.attrs.id,
|
|
219
|
-
}));
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
215
|
if (node.type === transform_1.schema.nodes.footnotes_element) {
|
|
224
216
|
if ((parent === null || parent === void 0 ? void 0 : parent.type) === transform_1.schema.nodes.table_element_footer) {
|
|
225
217
|
decorations.push(prosemirror_view_1.Decoration.node(pos, pos + node.nodeSize, {
|
|
@@ -91,9 +91,9 @@ export const updateTableInlineFootnoteLabels = (tr, table) => {
|
|
|
91
91
|
});
|
|
92
92
|
return tr;
|
|
93
93
|
};
|
|
94
|
-
export const getInlineFootnotes = (id,
|
|
94
|
+
export const getInlineFootnotes = (id, targetNode) => {
|
|
95
95
|
const inlineFootnotes = [];
|
|
96
|
-
|
|
96
|
+
targetNode.descendants((node, pos) => {
|
|
97
97
|
var _a;
|
|
98
98
|
if (node.type === schema.nodes.inline_footnote) {
|
|
99
99
|
const footnote = node;
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
import { isFootnoteNode, isInlineFootnoteNode, schema, } from '@manuscripts/transform';
|
|
17
17
|
import { isEqual } from 'lodash';
|
|
18
18
|
import { NodeSelection, Plugin, PluginKey } from 'prosemirror-state';
|
|
19
|
-
import { findParentNodeClosestToPos, findParentNodeOfType,
|
|
19
|
+
import { findParentNodeClosestToPos, findParentNodeOfType, } from 'prosemirror-utils';
|
|
20
20
|
import { Decoration, DecorationSet } from 'prosemirror-view';
|
|
21
21
|
import { alertIcon, deleteIcon } from '../../assets';
|
|
22
22
|
import { DeleteFootnoteDialog, } from '../../components/views/DeleteFootnoteDialog';
|
|
@@ -65,11 +65,20 @@ export const uncitedFootnoteWidget = () => () => {
|
|
|
65
65
|
element.innerHTML = alertIcon;
|
|
66
66
|
return element;
|
|
67
67
|
};
|
|
68
|
-
const deleteFootnoteWidget = (node, props,
|
|
68
|
+
const deleteFootnoteWidget = (node, props, id, tableElement) => (view, getPos) => {
|
|
69
69
|
const deleteBtn = document.createElement('span');
|
|
70
70
|
deleteBtn.className = 'delete-icon';
|
|
71
71
|
deleteBtn.innerHTML = deleteIcon;
|
|
72
|
-
|
|
72
|
+
const parentType = tableElement ? 'table ' : '';
|
|
73
|
+
const footnote = {
|
|
74
|
+
type: node.type === schema.nodes.footnote
|
|
75
|
+
? `${parentType}footnote`
|
|
76
|
+
: 'table general note',
|
|
77
|
+
message: node.type === schema.nodes.footnote
|
|
78
|
+
? `This action will entirely remove the ${parentType}footnote from the list because it will no longer be used.`
|
|
79
|
+
: 'This action will entirely remove the table general note.',
|
|
80
|
+
};
|
|
81
|
+
deleteBtn.addEventListener('mousedown', () => {
|
|
73
82
|
const handleDelete = () => {
|
|
74
83
|
let tr = view.state.tr;
|
|
75
84
|
const pos = getPos();
|
|
@@ -87,7 +96,8 @@ const deleteFootnoteWidget = (node, props, footnoteType, footnoteMessage, id, ta
|
|
|
87
96
|
}
|
|
88
97
|
}
|
|
89
98
|
if (node.type === schema.nodes.footnote && pos) {
|
|
90
|
-
const
|
|
99
|
+
const targetNode = tableElement ? tableElement.node : view.state.doc;
|
|
100
|
+
const inlineFootnotes = getInlineFootnotes(id, targetNode);
|
|
91
101
|
const nodeWithPos = findParentNodeClosestToPos(tr.doc.resolve(pos), (node) => node.type === schema.nodes.footnote);
|
|
92
102
|
if (nodeWithPos) {
|
|
93
103
|
const { pos: fnPos, node: fnNode } = nodeWithPos;
|
|
@@ -96,13 +106,13 @@ const deleteFootnoteWidget = (node, props, footnoteType, footnoteMessage, id, ta
|
|
|
96
106
|
if (inlineFootnotes) {
|
|
97
107
|
tr = view.state.tr;
|
|
98
108
|
inlineFootnotes.forEach((footnote) => {
|
|
99
|
-
const pos = footnote.pos + tableElement.pos;
|
|
109
|
+
const pos = footnote.pos + (tableElement ? tableElement.pos + 1 : 0);
|
|
100
110
|
if (footnote.node.attrs.rids.length > 1) {
|
|
101
111
|
const updatedRids = footnote.node.attrs.rids.filter((rid) => rid !== id);
|
|
102
112
|
tr.setNodeMarkup(tr.mapping.map(pos + 1), undefined, Object.assign(Object.assign({}, node.attrs), { rids: updatedRids }));
|
|
103
113
|
}
|
|
104
114
|
else {
|
|
105
|
-
tr.delete(tr.mapping.map(pos
|
|
115
|
+
tr.delete(tr.mapping.map(pos), tr.mapping.map(pos + footnote.node.nodeSize));
|
|
106
116
|
}
|
|
107
117
|
});
|
|
108
118
|
}
|
|
@@ -110,8 +120,8 @@ const deleteFootnoteWidget = (node, props, footnoteType, footnoteMessage, id, ta
|
|
|
110
120
|
view.dispatch(tr);
|
|
111
121
|
};
|
|
112
122
|
const componentProps = {
|
|
113
|
-
footnoteType:
|
|
114
|
-
footnoteMessage:
|
|
123
|
+
footnoteType: footnote.type,
|
|
124
|
+
footnoteMessage: footnote.message,
|
|
115
125
|
handleDelete: handleDelete,
|
|
116
126
|
};
|
|
117
127
|
ReactSubView(Object.assign(Object.assign({}, props), { dispatch: view.dispatch }), DeleteFootnoteDialog, componentProps, node, () => getPos(), view);
|
|
@@ -150,19 +160,30 @@ export default (props) => {
|
|
|
150
160
|
props: {
|
|
151
161
|
decorations: (state) => {
|
|
152
162
|
const decorations = [];
|
|
153
|
-
const
|
|
163
|
+
const tableElementFooter = findParentNodeOfType(schema.nodes.table_element_footer)(state.selection);
|
|
154
164
|
const tableElement = findParentNodeOfType(schema.nodes.table_element)(state.selection);
|
|
155
|
-
|
|
165
|
+
const footnote = findParentNodeOfType(schema.nodes.footnote)(state.selection);
|
|
166
|
+
let targetNode;
|
|
167
|
+
if (footnote) {
|
|
168
|
+
targetNode = footnote;
|
|
169
|
+
}
|
|
170
|
+
else if (tableElementFooter) {
|
|
171
|
+
targetNode = tableElementFooter;
|
|
172
|
+
}
|
|
173
|
+
const can = props.getCapabilities();
|
|
174
|
+
if (targetNode && can.editArticle) {
|
|
156
175
|
const parent = findParentNodeWithIdValue(state.selection);
|
|
157
176
|
if (parent) {
|
|
158
177
|
decorations.push(Decoration.node(parent.pos, parent.pos + parent.node.nodeSize, {
|
|
159
178
|
class: 'footnote-selected',
|
|
160
179
|
}));
|
|
180
|
+
decorations.push(Decoration.widget(targetNode.pos + (footnote ? 1 : 2), deleteFootnoteWidget(targetNode.node, props, targetNode.node.attrs.id, tableElement), {
|
|
181
|
+
key: targetNode.node.attrs.id,
|
|
182
|
+
}));
|
|
161
183
|
}
|
|
162
184
|
}
|
|
163
185
|
const { labels } = footnotesKey.getState(state);
|
|
164
186
|
let tableInlineFootnoteIds = undefined;
|
|
165
|
-
const can = props.getCapabilities();
|
|
166
187
|
state.doc.descendants((node, pos, parent) => {
|
|
167
188
|
var _a;
|
|
168
189
|
if (isFootnoteNode(node)) {
|
|
@@ -183,35 +204,6 @@ export default (props) => {
|
|
|
183
204
|
decorations.push(Decoration.widget(pos + node.nodeSize - 1, uncitedFootnoteWidget()));
|
|
184
205
|
}
|
|
185
206
|
}
|
|
186
|
-
if (can.editArticle) {
|
|
187
|
-
if (tableElement) {
|
|
188
|
-
const footnote = (() => {
|
|
189
|
-
switch (node.type) {
|
|
190
|
-
case schema.nodes.footnote:
|
|
191
|
-
return {
|
|
192
|
-
type: 'table footnote',
|
|
193
|
-
message: 'This action will entirely remove the table footnote from the list because it will no longer be used.',
|
|
194
|
-
};
|
|
195
|
-
default:
|
|
196
|
-
return {
|
|
197
|
-
type: 'table general note',
|
|
198
|
-
message: 'This action will entirely remove the table general note.',
|
|
199
|
-
};
|
|
200
|
-
}
|
|
201
|
-
})();
|
|
202
|
-
if (node.type === schema.nodes.footnote) {
|
|
203
|
-
decorations.push(Decoration.widget(pos + 2, deleteFootnoteWidget(node, props, footnote.type, footnote.message, node.attrs.id, tableElement), {
|
|
204
|
-
key: node.attrs.id,
|
|
205
|
-
}));
|
|
206
|
-
}
|
|
207
|
-
else if (node.type === schema.nodes.paragraph &&
|
|
208
|
-
(parent === null || parent === void 0 ? void 0 : parent.type) === schema.nodes.table_element_footer) {
|
|
209
|
-
decorations.push(Decoration.widget(pos + 1, deleteFootnoteWidget(parent, props, footnote.type, footnote.message, parent.attrs.id, tableElement), {
|
|
210
|
-
key: parent.attrs.id,
|
|
211
|
-
}));
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
207
|
if (node.type === schema.nodes.footnotes_element) {
|
|
216
208
|
if ((parent === null || parent === void 0 ? void 0 : parent.type) === schema.nodes.table_element_footer) {
|
|
217
209
|
decorations.push(Decoration.node(pos, pos + node.nodeSize, {
|
|
@@ -26,5 +26,5 @@ interface InlineFootnote {
|
|
|
26
26
|
node: InlineFootnoteNode;
|
|
27
27
|
pos: number;
|
|
28
28
|
}
|
|
29
|
-
export declare const getInlineFootnotes: (id: string,
|
|
29
|
+
export declare const getInlineFootnotes: (id: string, targetNode: ManuscriptNode) => InlineFootnote[];
|
|
30
30
|
export {};
|
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": "1.9.
|
|
4
|
+
"version": "1.9.5",
|
|
5
5
|
"repository": "github:Atypon-OpenSource/manuscripts-body-editor",
|
|
6
6
|
"license": "Apache-2.0",
|
|
7
7
|
"main": "dist/cjs",
|
|
@@ -111,4 +111,4 @@
|
|
|
111
111
|
"@types/react": "^17.0.2",
|
|
112
112
|
"prosemirror-tables": "^1.3.5"
|
|
113
113
|
}
|
|
114
|
-
}
|
|
114
|
+
}
|
package/styles/Editor.css
CHANGED
|
@@ -959,18 +959,19 @@
|
|
|
959
959
|
.ProseMirror .table-footnotes-element {
|
|
960
960
|
counter-reset: table_footnote;
|
|
961
961
|
}
|
|
962
|
-
.
|
|
963
|
-
display: none;
|
|
962
|
+
.delete-icon {
|
|
964
963
|
position: absolute;
|
|
965
964
|
right: -20px;
|
|
966
965
|
top: -13px;
|
|
967
966
|
cursor: pointer;
|
|
968
967
|
z-index: 1;
|
|
969
968
|
}
|
|
970
|
-
.
|
|
969
|
+
.delete-icon:hover svg path {
|
|
971
970
|
fill: #353535;
|
|
972
971
|
}
|
|
973
|
-
.ProseMirror .table-footnotes-element > div
|
|
972
|
+
.ProseMirror .table-footnotes-element > div,
|
|
973
|
+
.ProseMirror .block-footnotes_element > .block > div
|
|
974
|
+
{
|
|
974
975
|
position: relative;
|
|
975
976
|
}
|
|
976
977
|
|
|
@@ -990,29 +991,24 @@
|
|
|
990
991
|
margin-top: 0px;
|
|
991
992
|
}
|
|
992
993
|
|
|
993
|
-
.ProseMirror .
|
|
994
|
+
.ProseMirror .footnote-selected, .table-footer > div:has(> p.footnote-selected) > p {
|
|
994
995
|
background-color: #f2fbfc;
|
|
995
996
|
padding: 4px;
|
|
996
997
|
}
|
|
997
998
|
|
|
998
|
-
.ProseMirror .table-footer .footnote-selected .delete-icon ,.ProseMirror .table-footer .footnote-selected .deleted.rejected .delete-icon {
|
|
999
|
-
display: block;
|
|
1000
|
-
}
|
|
1001
999
|
.table-footer > div > p {
|
|
1002
1000
|
padding-bottom: 10px;
|
|
1003
1001
|
}
|
|
1004
1002
|
|
|
1005
|
-
.ProseMirror .table-footnotes-element .footnote-selected
|
|
1003
|
+
.ProseMirror .table-footnotes-element .footnote-selected,
|
|
1004
|
+
.ProseMirror .block-footnotes_element .footnote-selected
|
|
1005
|
+
{
|
|
1006
1006
|
border: 1px solid #bce7f6;
|
|
1007
1007
|
}
|
|
1008
1008
|
.table-footer > div:has(> p.footnote-selected) > p {
|
|
1009
1009
|
border-left: 1px solid #bce7f6;
|
|
1010
1010
|
border-right: 1px solid #bce7f6;
|
|
1011
1011
|
}
|
|
1012
|
-
.table-footer > div:has(> p.footnote-selected) > p:first-child .delete-icon {
|
|
1013
|
-
z-index: 2;
|
|
1014
|
-
display: block;
|
|
1015
|
-
}
|
|
1016
1012
|
.table-footer > div:has(> p.footnote-selected) > p:first-child {
|
|
1017
1013
|
border-top: 1px solid #bce7f6;
|
|
1018
1014
|
position: relative;
|