@manuscripts/body-editor 2.0.41 → 2.0.42
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 +4 -4
- package/dist/cjs/components/views/FootnotesSelector.js +173 -0
- package/dist/cjs/lib/context-menu.js +4 -4
- package/dist/cjs/{plugins/footnotes/footnotes-utils.js → lib/footnotes.js} +1 -1
- package/dist/cjs/plugins/footnotes/index.js +4 -4
- package/dist/cjs/plugins/table-footnote.js +3 -3
- package/dist/cjs/versions.js +1 -1
- package/dist/cjs/views/inline_footnote.js +6 -5
- package/dist/es/commands.js +1 -1
- package/dist/es/components/views/FootnotesSelector.js +143 -0
- package/dist/es/lib/context-menu.js +2 -2
- package/dist/es/{plugins/footnotes/footnotes-utils.js → lib/footnotes.js} +1 -1
- package/dist/es/plugins/footnotes/index.js +1 -1
- package/dist/es/plugins/table-footnote.js +1 -1
- package/dist/es/versions.js +1 -1
- package/dist/es/views/inline_footnote.js +3 -2
- package/dist/types/components/views/FootnotesSelector.d.ts +26 -0
- package/dist/types/{plugins/footnotes/footnotes-utils.d.ts → lib/footnotes.d.ts} +5 -1
- package/dist/types/versions.d.ts +1 -1
- package/dist/types/views/inline_footnote.d.ts +2 -1
- package/package.json +2 -2
package/dist/cjs/commands.js
CHANGED
|
@@ -27,13 +27,13 @@ const prosemirror_transform_1 = require("prosemirror-transform");
|
|
|
27
27
|
const prosemirror_utils_1 = require("prosemirror-utils");
|
|
28
28
|
const comments_1 = require("./lib/comments");
|
|
29
29
|
const doc_1 = require("./lib/doc");
|
|
30
|
+
const footnotes_1 = require("./lib/footnotes");
|
|
30
31
|
const helpers_1 = require("./lib/helpers");
|
|
31
32
|
const track_changes_utils_1 = require("./lib/track-changes-utils");
|
|
32
33
|
const utils_1 = require("./lib/utils");
|
|
33
34
|
const comments_2 = require("./plugins/comments");
|
|
34
35
|
const editor_props_1 = require("./plugins/editor-props");
|
|
35
|
-
const
|
|
36
|
-
const footnotes_utils_1 = require("./plugins/footnotes/footnotes-utils");
|
|
36
|
+
const footnotes_2 = require("./plugins/footnotes");
|
|
37
37
|
const markActive = (type) => (state) => {
|
|
38
38
|
const { from, $from, to, empty } = state.selection;
|
|
39
39
|
return empty
|
|
@@ -410,7 +410,7 @@ const insertFootnote = (state, tr, footnote) => {
|
|
|
410
410
|
};
|
|
411
411
|
exports.insertFootnote = insertFootnote;
|
|
412
412
|
const insertInlineFootnote = (kind) => (state, dispatch) => {
|
|
413
|
-
const fnState =
|
|
413
|
+
const fnState = footnotes_2.footnotesKey.getState(state);
|
|
414
414
|
const hasUnusedNodes = fnState && fnState.unusedFootnotes.size > 0;
|
|
415
415
|
const footnote = !hasUnusedNodes
|
|
416
416
|
? (0, exports.createFootnote)(state, kind)
|
|
@@ -1000,7 +1000,7 @@ const insertTableFootnote = (tableElementNode, position, view, inlineFootnote) =
|
|
|
1000
1000
|
if (footnotesElement &&
|
|
1001
1001
|
!(0, track_changes_utils_1.isDeleted)(footnotesElement.node) &&
|
|
1002
1002
|
!(0, track_changes_utils_1.isRejectedInsert)(footnotesElement.node)) {
|
|
1003
|
-
const footnotePos = (0,
|
|
1003
|
+
const footnotePos = (0, footnotes_1.getNewFootnotePos)(footnotesElement, footnoteIndex);
|
|
1004
1004
|
insertionPos = tr.mapping.map(position + footnotePos);
|
|
1005
1005
|
tr.insert(insertionPos, footnote);
|
|
1006
1006
|
}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*!
|
|
3
|
+
* © 2023 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 __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
18
|
+
if (k2 === undefined) k2 = k;
|
|
19
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
20
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
21
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
22
|
+
}
|
|
23
|
+
Object.defineProperty(o, k2, desc);
|
|
24
|
+
}) : (function(o, m, k, k2) {
|
|
25
|
+
if (k2 === undefined) k2 = k;
|
|
26
|
+
o[k2] = m[k];
|
|
27
|
+
}));
|
|
28
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
29
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
30
|
+
}) : function(o, v) {
|
|
31
|
+
o["default"] = v;
|
|
32
|
+
});
|
|
33
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
34
|
+
if (mod && mod.__esModule) return mod;
|
|
35
|
+
var result = {};
|
|
36
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
37
|
+
__setModuleDefault(result, mod);
|
|
38
|
+
return result;
|
|
39
|
+
};
|
|
40
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
41
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
42
|
+
};
|
|
43
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
44
|
+
exports.FootnotesSelector = void 0;
|
|
45
|
+
const style_guide_1 = require("@manuscripts/style-guide");
|
|
46
|
+
const react_1 = __importStar(require("react"));
|
|
47
|
+
const styled_components_1 = __importDefault(require("styled-components"));
|
|
48
|
+
const NotesContainer = styled_components_1.default.div `
|
|
49
|
+
height: 90vh;
|
|
50
|
+
max-height: 400px;
|
|
51
|
+
overflow-y: auto;
|
|
52
|
+
`;
|
|
53
|
+
const Actions = (0, styled_components_1.default)(style_guide_1.ButtonGroup) `
|
|
54
|
+
align-items: center;
|
|
55
|
+
box-shadow: 0 -2px 12px 0 rgba(216, 216, 216, 0.26);
|
|
56
|
+
display: flex;
|
|
57
|
+
justify-content: space-between;
|
|
58
|
+
padding: ${(props) => props.theme.grid.unit * 4}px;
|
|
59
|
+
`;
|
|
60
|
+
const Container = styled_components_1.default.div `
|
|
61
|
+
flex: 1;
|
|
62
|
+
font-family: ${(props) => props.theme.font.family.sans};
|
|
63
|
+
`;
|
|
64
|
+
const AddNewFootnote = (0, styled_components_1.default)(style_guide_1.ButtonGroup) `
|
|
65
|
+
button {
|
|
66
|
+
margin-right: ${(props) => props.theme.grid.unit * 8}px;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
button:hover,
|
|
70
|
+
button:active {
|
|
71
|
+
path {
|
|
72
|
+
stroke: ${(props) => props.theme.colors.brand.medium};
|
|
73
|
+
}
|
|
74
|
+
rect {
|
|
75
|
+
stroke: ${(props) => props.theme.colors.brand.medium};
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
`;
|
|
79
|
+
const FootnotesSelector = ({ notes, inlineFootnote, onAdd, onInsert, onCancel, addNewLabel }) => {
|
|
80
|
+
let selectedNotesMap;
|
|
81
|
+
if (inlineFootnote) {
|
|
82
|
+
const rids = inlineFootnote.attrs.rids;
|
|
83
|
+
const selectedNotes = notes.filter(({ node }) => rids.includes(node.attrs.id));
|
|
84
|
+
selectedNotesMap = new Map(selectedNotes.map(({ node }) => [node.attrs.id, node]));
|
|
85
|
+
}
|
|
86
|
+
const [selections, setSelections] = (0, react_1.useState)(new Map(selectedNotesMap));
|
|
87
|
+
const toggleSelection = (item) => {
|
|
88
|
+
const id = item.attrs.id;
|
|
89
|
+
if (selections.has(id)) {
|
|
90
|
+
selections.delete(id);
|
|
91
|
+
setSelections(new Map([...selections]));
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
selections.set(id, item);
|
|
95
|
+
setSelections(new Map([...selections]));
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
const isSelected = (item) => {
|
|
99
|
+
return selections.has(item.attrs.id);
|
|
100
|
+
};
|
|
101
|
+
const handleClick = () => {
|
|
102
|
+
return onInsert(notes.filter(({ node }) => selections.has(node.attrs.id)));
|
|
103
|
+
};
|
|
104
|
+
return (react_1.default.createElement(Container, null,
|
|
105
|
+
react_1.default.createElement(NotesContainer, null,
|
|
106
|
+
react_1.default.createElement(FootnotesList, { notes: notes, inlineFootnote: inlineFootnote, isSelected: isSelected, onSelect: toggleSelection })),
|
|
107
|
+
react_1.default.createElement(Actions, null,
|
|
108
|
+
react_1.default.createElement(AddNewFootnote, null,
|
|
109
|
+
react_1.default.createElement(style_guide_1.IconTextButton, { onClick: onAdd },
|
|
110
|
+
react_1.default.createElement(style_guide_1.AddNewIcon, null),
|
|
111
|
+
addNewLabel || 'Add new')),
|
|
112
|
+
react_1.default.createElement(style_guide_1.ButtonGroup, null,
|
|
113
|
+
react_1.default.createElement(style_guide_1.SecondaryButton, { onClick: onCancel }, "Cancel"),
|
|
114
|
+
react_1.default.createElement(style_guide_1.PrimaryButton, { onClick: handleClick, disabled: selections.size === 0 && !inlineFootnote }, inlineFootnote ? 'Update' : 'Insert')))));
|
|
115
|
+
};
|
|
116
|
+
exports.FootnotesSelector = FootnotesSelector;
|
|
117
|
+
const FootnotesList = ({ notes, isSelected, onSelect, inlineFootnote }) => {
|
|
118
|
+
const selectedNotes = [];
|
|
119
|
+
const remainingNotes = [];
|
|
120
|
+
notes.forEach((note) => {
|
|
121
|
+
const isNoteSelected = inlineFootnote && inlineFootnote.attrs.rids.includes(note.node.attrs.id);
|
|
122
|
+
if (isNoteSelected) {
|
|
123
|
+
selectedNotes.push(note);
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
remainingNotes.push(note);
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
return (react_1.default.createElement(NotesListContainer, null,
|
|
130
|
+
selectedNotes.map((note) => (react_1.default.createElement(FootnoteItem, { key: note.node.attrs.id, note: note, isSelected: isSelected, onSelect: onSelect }))),
|
|
131
|
+
selectedNotes.length > 0 && remainingNotes.length > 0 && react_1.default.createElement(Separator, null),
|
|
132
|
+
remainingNotes.map((note) => (react_1.default.createElement(FootnoteItem, { key: note.node.attrs.id, note: note, isSelected: isSelected, onSelect: onSelect })))));
|
|
133
|
+
};
|
|
134
|
+
const FootnoteItem = ({ note, isSelected, onSelect }) => {
|
|
135
|
+
var _a;
|
|
136
|
+
const { node, index } = note;
|
|
137
|
+
return (react_1.default.createElement(FootnoteItemContainer, { onClick: () => onSelect(node) },
|
|
138
|
+
react_1.default.createElement(StatusIcon, null, isSelected(node) ? (react_1.default.createElement(style_guide_1.AddedIcon, { "data-cy": 'plus-icon-ok' })) : (react_1.default.createElement(style_guide_1.AddIcon, { "data-cy": 'plus-icon' }))),
|
|
139
|
+
react_1.default.createElement(NoteText, null, (index ? index + '. ' : '') + ((_a = node.firstChild) === null || _a === void 0 ? void 0 : _a.textContent))));
|
|
140
|
+
};
|
|
141
|
+
const Separator = styled_components_1.default.div `
|
|
142
|
+
height: 0;
|
|
143
|
+
border-bottom: 1px solid #e2e2e2;
|
|
144
|
+
margin: 4px 0;
|
|
145
|
+
`;
|
|
146
|
+
const NotesListContainer = styled_components_1.default.div `
|
|
147
|
+
padding: ${(props) => props.theme.grid.unit * 6}px
|
|
148
|
+
${(props) => props.theme.grid.unit * 5}px;
|
|
149
|
+
flex: 1;
|
|
150
|
+
overflow-y: auto;
|
|
151
|
+
`;
|
|
152
|
+
const FootnoteItemContainer = styled_components_1.default.div `
|
|
153
|
+
cursor: pointer;
|
|
154
|
+
padding: ${(props) => props.theme.grid.unit * 2}px 0;
|
|
155
|
+
display: flex;
|
|
156
|
+
`;
|
|
157
|
+
const StatusIcon = styled_components_1.default.div `
|
|
158
|
+
flex-shrink: 1;
|
|
159
|
+
margin-right: ${(props) => props.theme.grid.unit * 3}px;
|
|
160
|
+
margin-left: ${(props) => props.theme.grid.unit}px;
|
|
161
|
+
height: ${(props) => props.theme.grid.unit * 6}px;
|
|
162
|
+
width: ${(props) => props.theme.grid.unit * 6}px;
|
|
163
|
+
display: inline-flex;
|
|
164
|
+
justify-content: center;
|
|
165
|
+
align-items: center;
|
|
166
|
+
cursor: pointer;
|
|
167
|
+
`;
|
|
168
|
+
const NoteText = styled_components_1.default.div `
|
|
169
|
+
color: ${(props) => props.theme.colors.text.primary};
|
|
170
|
+
flex: 1;
|
|
171
|
+
font-weight: ${(props) => props.theme.font.weight.normal};
|
|
172
|
+
margin-top: 2px;
|
|
173
|
+
`;
|
|
@@ -19,12 +19,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
19
19
|
};
|
|
20
20
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
21
|
exports.ContextMenu = exports.contextMenuBtnClass = exports.sectionLevel = void 0;
|
|
22
|
-
const style_guide_1 = require("@manuscripts/style-guide");
|
|
23
22
|
const transform_1 = require("@manuscripts/transform");
|
|
24
23
|
const prosemirror_utils_1 = require("prosemirror-utils");
|
|
25
24
|
const commands_1 = require("../commands");
|
|
26
|
-
const
|
|
25
|
+
const FootnotesSelector_1 = require("../components/views/FootnotesSelector");
|
|
27
26
|
const ReactSubView_1 = __importDefault(require("../views/ReactSubView"));
|
|
27
|
+
const footnotes_1 = require("./footnotes");
|
|
28
28
|
const popper_1 = require("./popper");
|
|
29
29
|
const track_changes_utils_1 = require("./track-changes-utils");
|
|
30
30
|
const utils_1 = require("./utils");
|
|
@@ -211,7 +211,7 @@ class ContextMenu {
|
|
|
211
211
|
(0, commands_1.insertTableFootnote)(this.node, this.getPos(), this.view);
|
|
212
212
|
}
|
|
213
213
|
else {
|
|
214
|
-
const tablesFootnoteLabels = (0,
|
|
214
|
+
const tablesFootnoteLabels = (0, footnotes_1.buildTableFootnoteLabels)(this.node);
|
|
215
215
|
const footnotesWithPos = (0, prosemirror_utils_1.findChildrenByType)(footnotesElementWithPos.node, transform_1.schema.nodes.footnote);
|
|
216
216
|
const footnotes = footnotesWithPos
|
|
217
217
|
.filter(({ node }) => !(0, track_changes_utils_1.isDeleted)(node) && !(0, track_changes_utils_1.isRejectedInsert)(node))
|
|
@@ -224,7 +224,7 @@ class ContextMenu {
|
|
|
224
224
|
? targetDom.node.parentNode
|
|
225
225
|
: targetDom.node;
|
|
226
226
|
if (targetNode instanceof Element && this.props) {
|
|
227
|
-
const popperContainer = (0, ReactSubView_1.default)(Object.assign(Object.assign({}, this.props), { dispatch: this.view.dispatch }),
|
|
227
|
+
const popperContainer = (0, ReactSubView_1.default)(Object.assign(Object.assign({}, this.props), { dispatch: this.view.dispatch }), FootnotesSelector_1.FootnotesSelector, {
|
|
228
228
|
notes: footnotes,
|
|
229
229
|
onAdd: () => {
|
|
230
230
|
var _a;
|
|
@@ -20,7 +20,7 @@ const track_changes_plugin_1 = require("@manuscripts/track-changes-plugin");
|
|
|
20
20
|
const transform_1 = require("@manuscripts/transform");
|
|
21
21
|
const prosemirror_model_1 = require("prosemirror-model");
|
|
22
22
|
const prosemirror_utils_1 = require("prosemirror-utils");
|
|
23
|
-
const track_changes_utils_1 = require("
|
|
23
|
+
const track_changes_utils_1 = require("./track-changes-utils");
|
|
24
24
|
const findTableInlineFootnoteIds = ($pos) => {
|
|
25
25
|
var _a;
|
|
26
26
|
const tableElement = (_a = (0, prosemirror_utils_1.findParentNodeClosestToPos)($pos, (node) => node.type === transform_1.schema.nodes.table_element)) === null || _a === void 0 ? void 0 : _a.node;
|
|
@@ -30,10 +30,10 @@ const react_1 = require("react");
|
|
|
30
30
|
const server_1 = require("react-dom/server");
|
|
31
31
|
const commands_1 = require("../../commands");
|
|
32
32
|
const DeleteFootnoteDialog_1 = require("../../components/views/DeleteFootnoteDialog");
|
|
33
|
+
const footnotes_1 = require("../../lib/footnotes");
|
|
33
34
|
const utils_1 = require("../../lib/utils");
|
|
34
35
|
const ReactSubView_1 = __importDefault(require("../../views/ReactSubView"));
|
|
35
36
|
const placeholder_1 = require("../placeholder");
|
|
36
|
-
const footnotes_utils_1 = require("./footnotes-utils");
|
|
37
37
|
exports.footnotesKey = new prosemirror_state_1.PluginKey('footnotes');
|
|
38
38
|
const scrollToInlineFootnote = (rid, view) => {
|
|
39
39
|
view.state.doc.descendants((node, pos) => {
|
|
@@ -89,7 +89,7 @@ const deleteFootnoteWidget = (node, props, id, tableElement, tableElementFooter)
|
|
|
89
89
|
}
|
|
90
90
|
if (node.type === transform_1.schema.nodes.footnote && pos) {
|
|
91
91
|
const targetNode = tableElement ? tableElement.node : view.state.doc;
|
|
92
|
-
const inlineFootnotes = (0,
|
|
92
|
+
const inlineFootnotes = (0, footnotes_1.getInlineFootnotes)(id, targetNode);
|
|
93
93
|
const footnotesElement = (0, prosemirror_utils_1.findParentNodeClosestToPos)(tr.doc.resolve(pos), (node) => node.type === transform_1.schema.nodes.footnotes_element);
|
|
94
94
|
if ((footnotesElement === null || footnotesElement === void 0 ? void 0 : footnotesElement.node.childCount) === 1 &&
|
|
95
95
|
(tableElementFooter === null || tableElementFooter === void 0 ? void 0 : tableElementFooter.node.childCount) === 1) {
|
|
@@ -158,7 +158,7 @@ const buildPluginState = (doc) => {
|
|
|
158
158
|
inlineFootnotes.sort((a, b) => a[1] - b[1]);
|
|
159
159
|
inlineFootnotes.forEach(([node]) => {
|
|
160
160
|
node.attrs.rids.forEach((rid) => {
|
|
161
|
-
labels.set(rid, (0,
|
|
161
|
+
labels.set(rid, (0, footnotes_1.getAlphaOrderIndices)(index++));
|
|
162
162
|
});
|
|
163
163
|
});
|
|
164
164
|
const footnotesReordered = [];
|
|
@@ -277,7 +277,7 @@ exports.default = (props) => {
|
|
|
277
277
|
decorations.push(prosemirror_view_1.Decoration.node(pos, pos + node.nodeSize, {
|
|
278
278
|
class: 'table-footnotes-element',
|
|
279
279
|
}));
|
|
280
|
-
tableInlineFootnoteIds = (0,
|
|
280
|
+
tableInlineFootnoteIds = (0, footnotes_1.findTableInlineFootnoteIds)(state.doc.resolve(pos));
|
|
281
281
|
}
|
|
282
282
|
}
|
|
283
283
|
if ((0, transform_1.isFootnoteNode)(node)) {
|
|
@@ -4,7 +4,7 @@ const transform_1 = require("@manuscripts/transform");
|
|
|
4
4
|
const prosemirror_state_1 = require("prosemirror-state");
|
|
5
5
|
const prosemirror_transform_1 = require("prosemirror-transform");
|
|
6
6
|
const prosemirror_utils_1 = require("prosemirror-utils");
|
|
7
|
-
const
|
|
7
|
+
const footnotes_1 = require("../lib/footnotes");
|
|
8
8
|
const isInlineFootnoteChange = (step, oldState, newState) => {
|
|
9
9
|
var _a, _b;
|
|
10
10
|
return step.slice.size > 0
|
|
@@ -38,8 +38,8 @@ exports.default = () => {
|
|
|
38
38
|
if (!table || !footnotesElementWithPos) {
|
|
39
39
|
return null;
|
|
40
40
|
}
|
|
41
|
-
(0,
|
|
42
|
-
(0,
|
|
41
|
+
(0, footnotes_1.updateTableInlineFootnoteLabels)(tr, table);
|
|
42
|
+
(0, footnotes_1.orderTableFootnotes)(tr, footnotesElementWithPos, tr.mapping.map(table.pos));
|
|
43
43
|
return tr;
|
|
44
44
|
},
|
|
45
45
|
});
|
package/dist/cjs/versions.js
CHANGED
|
@@ -24,9 +24,10 @@ const transform_1 = require("@manuscripts/transform");
|
|
|
24
24
|
const prosemirror_state_1 = require("prosemirror-state");
|
|
25
25
|
const prosemirror_utils_1 = require("prosemirror-utils");
|
|
26
26
|
const commands_1 = require("../commands");
|
|
27
|
+
const FootnotesSelector_1 = require("../components/views/FootnotesSelector");
|
|
28
|
+
const footnotes_1 = require("../lib/footnotes");
|
|
27
29
|
const track_changes_utils_1 = require("../lib/track-changes-utils");
|
|
28
|
-
const
|
|
29
|
-
const footnotes_utils_1 = require("../plugins/footnotes/footnotes-utils");
|
|
30
|
+
const footnotes_2 = require("../plugins/footnotes");
|
|
30
31
|
const base_node_view_1 = require("./base_node_view");
|
|
31
32
|
const creators_1 = require("./creators");
|
|
32
33
|
const ReactSubView_1 = __importDefault(require("./ReactSubView"));
|
|
@@ -84,7 +85,7 @@ class InlineFootnoteView extends base_node_view_1.BaseNodeView {
|
|
|
84
85
|
if (!this.props.getCapabilities().editArticle) {
|
|
85
86
|
return;
|
|
86
87
|
}
|
|
87
|
-
const fnState =
|
|
88
|
+
const fnState = footnotes_2.footnotesKey.getState(this.view.state);
|
|
88
89
|
if (fnState) {
|
|
89
90
|
this.activateModal({
|
|
90
91
|
notes: Array.from(fnState.unusedFootnotes.values()).map((n) => ({
|
|
@@ -147,7 +148,7 @@ class InlineFootnoteView extends base_node_view_1.BaseNodeView {
|
|
|
147
148
|
const footnotesElement = (_a = (0, prosemirror_utils_1.findChildrenByType)(tableElement.node, transform_1.schema.nodes.footnotes_element).pop()) === null || _a === void 0 ? void 0 : _a.node;
|
|
148
149
|
let footnotes = [];
|
|
149
150
|
if (footnotesElement) {
|
|
150
|
-
const tablesFootnoteLabels = (0,
|
|
151
|
+
const tablesFootnoteLabels = (0, footnotes_1.buildTableFootnoteLabels)(tableElement.node);
|
|
151
152
|
footnotes = (0, prosemirror_utils_1.findChildrenByType)(footnotesElement, transform_1.schema.nodes.footnote)
|
|
152
153
|
.filter(({ node }) => !(0, track_changes_utils_1.isDeleted)(node) && !(0, track_changes_utils_1.isRejectedInsert)(node))
|
|
153
154
|
.map(({ node }) => ({
|
|
@@ -203,7 +204,7 @@ class InlineFootnoteView extends base_node_view_1.BaseNodeView {
|
|
|
203
204
|
onCancel: this.destroy,
|
|
204
205
|
inlineFootnote: this.node,
|
|
205
206
|
};
|
|
206
|
-
this.popperContainer = (0, ReactSubView_1.default)(Object.assign(Object.assign({}, this.props), { dispatch: this.view.dispatch }),
|
|
207
|
+
this.popperContainer = (0, ReactSubView_1.default)(Object.assign(Object.assign({}, this.props), { dispatch: this.view.dispatch }), FootnotesSelector_1.FootnotesSelector, Object.assign(Object.assign({}, defaultModal), modalProps), this.node, this.getPos, this.view, 'footnote-editor');
|
|
207
208
|
this.props.popper.show(this.dom, this.popperContainer, 'auto', false);
|
|
208
209
|
}
|
|
209
210
|
}
|
package/dist/es/commands.js
CHANGED
|
@@ -24,13 +24,13 @@ import { findWrapping, liftTarget, ReplaceAroundStep, } from 'prosemirror-transf
|
|
|
24
24
|
import { findChildrenByType, findParentNodeOfType, hasParentNodeOfType, } from 'prosemirror-utils';
|
|
25
25
|
import { getCommentKey, getCommentRange } from './lib/comments';
|
|
26
26
|
import { findBackmatter, findBibliographySection, findBody, insertSupplementsNode, } from './lib/doc';
|
|
27
|
+
import { getNewFootnotePos } from './lib/footnotes';
|
|
27
28
|
import { findWordBoundaries, isNodeOfType, nearestAncestor, } from './lib/helpers';
|
|
28
29
|
import { isDeleted, isRejectedInsert } from './lib/track-changes-utils';
|
|
29
30
|
import { findParentNodeWithId, getChildOfType, getMatchingChild, } from './lib/utils';
|
|
30
31
|
import { setCommentSelection } from './plugins/comments';
|
|
31
32
|
import { getEditorProps } from './plugins/editor-props';
|
|
32
33
|
import { footnotesKey } from './plugins/footnotes';
|
|
33
|
-
import { getNewFootnotePos } from './plugins/footnotes/footnotes-utils';
|
|
34
34
|
export const markActive = (type) => (state) => {
|
|
35
35
|
const { from, $from, to, empty } = state.selection;
|
|
36
36
|
return empty
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* © 2023 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 { AddedIcon, AddIcon, AddNewIcon, ButtonGroup, IconTextButton, PrimaryButton, SecondaryButton, } from '@manuscripts/style-guide';
|
|
17
|
+
import React, { useState } from 'react';
|
|
18
|
+
import styled from 'styled-components';
|
|
19
|
+
const NotesContainer = styled.div `
|
|
20
|
+
height: 90vh;
|
|
21
|
+
max-height: 400px;
|
|
22
|
+
overflow-y: auto;
|
|
23
|
+
`;
|
|
24
|
+
const Actions = styled(ButtonGroup) `
|
|
25
|
+
align-items: center;
|
|
26
|
+
box-shadow: 0 -2px 12px 0 rgba(216, 216, 216, 0.26);
|
|
27
|
+
display: flex;
|
|
28
|
+
justify-content: space-between;
|
|
29
|
+
padding: ${(props) => props.theme.grid.unit * 4}px;
|
|
30
|
+
`;
|
|
31
|
+
const Container = styled.div `
|
|
32
|
+
flex: 1;
|
|
33
|
+
font-family: ${(props) => props.theme.font.family.sans};
|
|
34
|
+
`;
|
|
35
|
+
const AddNewFootnote = styled(ButtonGroup) `
|
|
36
|
+
button {
|
|
37
|
+
margin-right: ${(props) => props.theme.grid.unit * 8}px;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
button:hover,
|
|
41
|
+
button:active {
|
|
42
|
+
path {
|
|
43
|
+
stroke: ${(props) => props.theme.colors.brand.medium};
|
|
44
|
+
}
|
|
45
|
+
rect {
|
|
46
|
+
stroke: ${(props) => props.theme.colors.brand.medium};
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
`;
|
|
50
|
+
export const FootnotesSelector = ({ notes, inlineFootnote, onAdd, onInsert, onCancel, addNewLabel }) => {
|
|
51
|
+
let selectedNotesMap;
|
|
52
|
+
if (inlineFootnote) {
|
|
53
|
+
const rids = inlineFootnote.attrs.rids;
|
|
54
|
+
const selectedNotes = notes.filter(({ node }) => rids.includes(node.attrs.id));
|
|
55
|
+
selectedNotesMap = new Map(selectedNotes.map(({ node }) => [node.attrs.id, node]));
|
|
56
|
+
}
|
|
57
|
+
const [selections, setSelections] = useState(new Map(selectedNotesMap));
|
|
58
|
+
const toggleSelection = (item) => {
|
|
59
|
+
const id = item.attrs.id;
|
|
60
|
+
if (selections.has(id)) {
|
|
61
|
+
selections.delete(id);
|
|
62
|
+
setSelections(new Map([...selections]));
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
selections.set(id, item);
|
|
66
|
+
setSelections(new Map([...selections]));
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
const isSelected = (item) => {
|
|
70
|
+
return selections.has(item.attrs.id);
|
|
71
|
+
};
|
|
72
|
+
const handleClick = () => {
|
|
73
|
+
return onInsert(notes.filter(({ node }) => selections.has(node.attrs.id)));
|
|
74
|
+
};
|
|
75
|
+
return (React.createElement(Container, null,
|
|
76
|
+
React.createElement(NotesContainer, null,
|
|
77
|
+
React.createElement(FootnotesList, { notes: notes, inlineFootnote: inlineFootnote, isSelected: isSelected, onSelect: toggleSelection })),
|
|
78
|
+
React.createElement(Actions, null,
|
|
79
|
+
React.createElement(AddNewFootnote, null,
|
|
80
|
+
React.createElement(IconTextButton, { onClick: onAdd },
|
|
81
|
+
React.createElement(AddNewIcon, null),
|
|
82
|
+
addNewLabel || 'Add new')),
|
|
83
|
+
React.createElement(ButtonGroup, null,
|
|
84
|
+
React.createElement(SecondaryButton, { onClick: onCancel }, "Cancel"),
|
|
85
|
+
React.createElement(PrimaryButton, { onClick: handleClick, disabled: selections.size === 0 && !inlineFootnote }, inlineFootnote ? 'Update' : 'Insert')))));
|
|
86
|
+
};
|
|
87
|
+
const FootnotesList = ({ notes, isSelected, onSelect, inlineFootnote }) => {
|
|
88
|
+
const selectedNotes = [];
|
|
89
|
+
const remainingNotes = [];
|
|
90
|
+
notes.forEach((note) => {
|
|
91
|
+
const isNoteSelected = inlineFootnote && inlineFootnote.attrs.rids.includes(note.node.attrs.id);
|
|
92
|
+
if (isNoteSelected) {
|
|
93
|
+
selectedNotes.push(note);
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
remainingNotes.push(note);
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
return (React.createElement(NotesListContainer, null,
|
|
100
|
+
selectedNotes.map((note) => (React.createElement(FootnoteItem, { key: note.node.attrs.id, note: note, isSelected: isSelected, onSelect: onSelect }))),
|
|
101
|
+
selectedNotes.length > 0 && remainingNotes.length > 0 && React.createElement(Separator, null),
|
|
102
|
+
remainingNotes.map((note) => (React.createElement(FootnoteItem, { key: note.node.attrs.id, note: note, isSelected: isSelected, onSelect: onSelect })))));
|
|
103
|
+
};
|
|
104
|
+
const FootnoteItem = ({ note, isSelected, onSelect }) => {
|
|
105
|
+
var _a;
|
|
106
|
+
const { node, index } = note;
|
|
107
|
+
return (React.createElement(FootnoteItemContainer, { onClick: () => onSelect(node) },
|
|
108
|
+
React.createElement(StatusIcon, null, isSelected(node) ? (React.createElement(AddedIcon, { "data-cy": 'plus-icon-ok' })) : (React.createElement(AddIcon, { "data-cy": 'plus-icon' }))),
|
|
109
|
+
React.createElement(NoteText, null, (index ? index + '. ' : '') + ((_a = node.firstChild) === null || _a === void 0 ? void 0 : _a.textContent))));
|
|
110
|
+
};
|
|
111
|
+
const Separator = styled.div `
|
|
112
|
+
height: 0;
|
|
113
|
+
border-bottom: 1px solid #e2e2e2;
|
|
114
|
+
margin: 4px 0;
|
|
115
|
+
`;
|
|
116
|
+
const NotesListContainer = styled.div `
|
|
117
|
+
padding: ${(props) => props.theme.grid.unit * 6}px
|
|
118
|
+
${(props) => props.theme.grid.unit * 5}px;
|
|
119
|
+
flex: 1;
|
|
120
|
+
overflow-y: auto;
|
|
121
|
+
`;
|
|
122
|
+
const FootnoteItemContainer = styled.div `
|
|
123
|
+
cursor: pointer;
|
|
124
|
+
padding: ${(props) => props.theme.grid.unit * 2}px 0;
|
|
125
|
+
display: flex;
|
|
126
|
+
`;
|
|
127
|
+
const StatusIcon = styled.div `
|
|
128
|
+
flex-shrink: 1;
|
|
129
|
+
margin-right: ${(props) => props.theme.grid.unit * 3}px;
|
|
130
|
+
margin-left: ${(props) => props.theme.grid.unit}px;
|
|
131
|
+
height: ${(props) => props.theme.grid.unit * 6}px;
|
|
132
|
+
width: ${(props) => props.theme.grid.unit * 6}px;
|
|
133
|
+
display: inline-flex;
|
|
134
|
+
justify-content: center;
|
|
135
|
+
align-items: center;
|
|
136
|
+
cursor: pointer;
|
|
137
|
+
`;
|
|
138
|
+
const NoteText = styled.div `
|
|
139
|
+
color: ${(props) => props.theme.colors.text.primary};
|
|
140
|
+
flex: 1;
|
|
141
|
+
font-weight: ${(props) => props.theme.font.weight.normal};
|
|
142
|
+
margin-top: 2px;
|
|
143
|
+
`;
|
|
@@ -13,12 +13,12 @@
|
|
|
13
13
|
* See the License for the specific language governing permissions and
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
|
-
import { FootnotesSelector } from '@manuscripts/style-guide';
|
|
17
16
|
import { getListType, isInBibliographySection, nodeNames, schema, } from '@manuscripts/transform';
|
|
18
17
|
import { findChildrenByType, hasParentNodeOfType } from 'prosemirror-utils';
|
|
19
18
|
import { addNodeComment, createBlock, findPosBeforeFirstSubsection, insertGeneralFootnote, insertTableFootnote, } from '../commands';
|
|
20
|
-
import {
|
|
19
|
+
import { FootnotesSelector } from '../components/views/FootnotesSelector';
|
|
21
20
|
import ReactSubView from '../views/ReactSubView';
|
|
21
|
+
import { buildTableFootnoteLabels } from './footnotes';
|
|
22
22
|
import { PopperManager } from './popper';
|
|
23
23
|
import { getActualAttrs, isDeleted, isRejectedInsert, } from './track-changes-utils';
|
|
24
24
|
import { getChildOfType, isChildOfNodeTypes } from './utils';
|
|
@@ -17,7 +17,7 @@ import { skipTracking } from '@manuscripts/track-changes-plugin';
|
|
|
17
17
|
import { isFootnoteNode, schema, } from '@manuscripts/transform';
|
|
18
18
|
import { Fragment } from 'prosemirror-model';
|
|
19
19
|
import { findChildren, findChildrenByType, findParentNodeClosestToPos, } from 'prosemirror-utils';
|
|
20
|
-
import { isRejectedInsert } from '
|
|
20
|
+
import { isRejectedInsert } from './track-changes-utils';
|
|
21
21
|
export const findTableInlineFootnoteIds = ($pos) => {
|
|
22
22
|
var _a;
|
|
23
23
|
const tableElement = (_a = findParentNodeClosestToPos($pos, (node) => node.type === schema.nodes.table_element)) === null || _a === void 0 ? void 0 : _a.node;
|
|
@@ -24,10 +24,10 @@ import { createElement } from 'react';
|
|
|
24
24
|
import { renderToStaticMarkup } from 'react-dom/server';
|
|
25
25
|
import { isTextSelection } from '../../commands';
|
|
26
26
|
import { DeleteFootnoteDialog, } from '../../components/views/DeleteFootnoteDialog';
|
|
27
|
+
import { findTableInlineFootnoteIds, getAlphaOrderIndices, getInlineFootnotes, } from '../../lib/footnotes';
|
|
27
28
|
import { getChildOfType } from '../../lib/utils';
|
|
28
29
|
import ReactSubView from '../../views/ReactSubView';
|
|
29
30
|
import { placeholderWidget } from '../placeholder';
|
|
30
|
-
import { findTableInlineFootnoteIds, getAlphaOrderIndices, getInlineFootnotes, } from './footnotes-utils';
|
|
31
31
|
export const footnotesKey = new PluginKey('footnotes');
|
|
32
32
|
const scrollToInlineFootnote = (rid, view) => {
|
|
33
33
|
view.state.doc.descendants((node, pos) => {
|
|
@@ -2,7 +2,7 @@ import { schema } from '@manuscripts/transform';
|
|
|
2
2
|
import { Plugin } from 'prosemirror-state';
|
|
3
3
|
import { ReplaceStep } from 'prosemirror-transform';
|
|
4
4
|
import { findChildrenByType, findParentNodeClosestToPos, } from 'prosemirror-utils';
|
|
5
|
-
import { orderTableFootnotes, updateTableInlineFootnoteLabels, } from '
|
|
5
|
+
import { orderTableFootnotes, updateTableInlineFootnoteLabels, } from '../lib/footnotes';
|
|
6
6
|
const isInlineFootnoteChange = (step, oldState, newState) => {
|
|
7
7
|
var _a, _b;
|
|
8
8
|
return step.slice.size > 0
|
package/dist/es/versions.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const VERSION = '2.0.
|
|
1
|
+
export const VERSION = '2.0.42';
|
|
2
2
|
export const MATHJAX_VERSION = '3.2.2';
|
|
@@ -13,14 +13,15 @@
|
|
|
13
13
|
* See the License for the specific language governing permissions and
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
|
-
import { ContextMenu
|
|
16
|
+
import { ContextMenu } from '@manuscripts/style-guide';
|
|
17
17
|
import { schema, } from '@manuscripts/transform';
|
|
18
18
|
import { NodeSelection, TextSelection } from 'prosemirror-state';
|
|
19
19
|
import { findChildrenByType, findParentNodeClosestToPos, } from 'prosemirror-utils';
|
|
20
20
|
import { createFootnote, insertFootnote, insertTableFootnote, } from '../commands';
|
|
21
|
+
import { FootnotesSelector } from '../components/views/FootnotesSelector';
|
|
22
|
+
import { buildTableFootnoteLabels } from '../lib/footnotes';
|
|
21
23
|
import { getChangeClasses, isDeleted, isPendingInsert, isRejectedInsert, } from '../lib/track-changes-utils';
|
|
22
24
|
import { footnotesKey } from '../plugins/footnotes';
|
|
23
|
-
import { buildTableFootnoteLabels } from '../plugins/footnotes/footnotes-utils';
|
|
24
25
|
import { BaseNodeView } from './base_node_view';
|
|
25
26
|
import { createNodeView } from './creators';
|
|
26
27
|
import ReactSubView from './ReactSubView';
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* © 2023 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 { InlineFootnoteNode } from '@manuscripts/transform';
|
|
17
|
+
import React from 'react';
|
|
18
|
+
import { FootnoteWithIndex } from '../../lib/footnotes';
|
|
19
|
+
export declare const FootnotesSelector: React.FC<{
|
|
20
|
+
notes: FootnoteWithIndex[];
|
|
21
|
+
inlineFootnote?: InlineFootnoteNode;
|
|
22
|
+
onAdd: () => void;
|
|
23
|
+
onInsert: (notes: FootnoteWithIndex[]) => void;
|
|
24
|
+
onCancel: () => void;
|
|
25
|
+
addNewLabel?: string;
|
|
26
|
+
}>;
|
|
@@ -13,10 +13,14 @@
|
|
|
13
13
|
* See the License for the specific language governing permissions and
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
|
-
import { InlineFootnoteNode, ManuscriptNode } from '@manuscripts/transform';
|
|
16
|
+
import { FootnoteNode, InlineFootnoteNode, ManuscriptNode } from '@manuscripts/transform';
|
|
17
17
|
import { ResolvedPos } from 'prosemirror-model';
|
|
18
18
|
import { Transaction } from 'prosemirror-state';
|
|
19
19
|
import { ContentNodeWithPos, NodeWithPos } from 'prosemirror-utils';
|
|
20
|
+
export type FootnoteWithIndex = {
|
|
21
|
+
node: FootnoteNode;
|
|
22
|
+
index?: string;
|
|
23
|
+
};
|
|
20
24
|
export declare const findTableInlineFootnoteIds: ($pos: ResolvedPos) => Set<string>;
|
|
21
25
|
export declare const getNewFootnotePos: (footnotesElement: NodeWithPos, footnoteIndex: number) => number;
|
|
22
26
|
export declare const buildTableFootnoteLabels: (node: ManuscriptNode) => Map<string, string | undefined>;
|
package/dist/types/versions.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const VERSION = "2.0.
|
|
1
|
+
export declare const VERSION = "2.0.42";
|
|
2
2
|
export declare const MATHJAX_VERSION = "3.2.2";
|
|
@@ -13,10 +13,11 @@
|
|
|
13
13
|
* See the License for the specific language governing permissions and
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
|
-
import { FootnotesSelector, FootnoteWithIndex } from '@manuscripts/style-guide';
|
|
17
16
|
import { ManuscriptNodeView } from '@manuscripts/transform';
|
|
18
17
|
import { History } from 'history';
|
|
19
18
|
import { ContentNodeWithPos } from 'prosemirror-utils';
|
|
19
|
+
import { FootnotesSelector } from '../components/views/FootnotesSelector';
|
|
20
|
+
import { FootnoteWithIndex } from '../lib/footnotes';
|
|
20
21
|
import { BaseNodeProps, BaseNodeView } from './base_node_view';
|
|
21
22
|
import { EditableBlockProps } from './editable_block';
|
|
22
23
|
export interface InlineFootnoteProps extends BaseNodeProps {
|
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": "2.0.
|
|
4
|
+
"version": "2.0.42",
|
|
5
5
|
"repository": "github:Atypon-OpenSource/manuscripts-body-editor",
|
|
6
6
|
"license": "Apache-2.0",
|
|
7
7
|
"main": "dist/cjs",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"@iarna/word-count": "^1.1.2",
|
|
33
33
|
"@manuscripts/json-schema": "2.2.11",
|
|
34
34
|
"@manuscripts/library": "1.3.11",
|
|
35
|
-
"@manuscripts/style-guide": "2.0.
|
|
35
|
+
"@manuscripts/style-guide": "2.0.18",
|
|
36
36
|
"@manuscripts/track-changes-plugin": "1.7.17",
|
|
37
37
|
"@manuscripts/transform": "2.3.31",
|
|
38
38
|
"@popperjs/core": "^2.11.8",
|