@manuscripts/body-editor 1.9.6 → 1.9.7-LEAN-3136
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 +26 -8
- package/dist/cjs/configs/ManuscriptsEditor.js +20 -14
- package/dist/cjs/configs/editor-views.js +1 -1
- package/dist/cjs/plugins/affiliations.js +3 -0
- package/dist/cjs/plugins/bibliography/index.js +1 -1
- package/dist/cjs/plugins/footnotes/footnotes-utils.js +33 -1
- package/dist/cjs/plugins/footnotes/index.js +77 -26
- package/dist/cjs/plugins/highlight/index.js +6 -5
- package/dist/cjs/plugins/selected-suggestion-ui.js +8 -4
- package/dist/cjs/plugins/table-footnote.js +3 -0
- package/dist/cjs/views/base_node_view.js +1 -1
- package/dist/cjs/views/bibliography_element.js +6 -0
- package/dist/cjs/views/citation.js +3 -0
- package/dist/cjs/views/citation_editable.js +6 -0
- package/dist/cjs/views/footnotes_element.js +3 -1
- package/dist/cjs/views/inline_footnote.js +17 -2
- package/dist/es/commands.js +27 -9
- package/dist/es/configs/ManuscriptsEditor.js +20 -14
- package/dist/es/configs/editor-views.js +1 -1
- package/dist/es/plugins/affiliations.js +3 -0
- package/dist/es/plugins/bibliography/index.js +1 -1
- package/dist/es/plugins/footnotes/footnotes-utils.js +31 -0
- package/dist/es/plugins/footnotes/index.js +78 -27
- package/dist/es/plugins/highlight/index.js +6 -5
- package/dist/es/plugins/selected-suggestion-ui.js +8 -4
- package/dist/es/plugins/table-footnote.js +3 -0
- package/dist/es/views/base_node_view.js +1 -1
- package/dist/es/views/bibliography_element.js +6 -0
- package/dist/es/views/citation.js +3 -0
- package/dist/es/views/citation_editable.js +6 -0
- package/dist/es/views/footnotes_element.js +3 -1
- package/dist/es/views/inline_footnote.js +17 -2
- package/dist/types/plugins/bibliography/index.d.ts +1 -1
- package/dist/types/plugins/footnotes/footnotes-utils.d.ts +1 -0
- package/dist/types/plugins/footnotes/index.d.ts +5 -3
- package/dist/types/views/footnotes_element.d.ts +3 -3
- package/package.json +4 -4
- package/styles/AdvancedEditor.css +6 -8
- package/styles/Editor.css +7 -3
package/dist/cjs/commands.js
CHANGED
|
@@ -59,7 +59,10 @@ const blockActive = (type) => (state) => {
|
|
|
59
59
|
};
|
|
60
60
|
exports.blockActive = blockActive;
|
|
61
61
|
const canInsert = (type) => (state) => {
|
|
62
|
-
const { $from } = state.selection;
|
|
62
|
+
const { $from, $to } = state.selection;
|
|
63
|
+
if ($from.node().type === transform_1.schema.nodes.title && $from.pos === $to.pos) {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
63
66
|
for (let d = $from.depth; d >= 0; d--) {
|
|
64
67
|
const index = $from.index(d);
|
|
65
68
|
if ($from.node(d).canReplaceWith(index, index, type)) {
|
|
@@ -324,12 +327,24 @@ const insertInlineFootnote = (kind) => (state, dispatch) => {
|
|
|
324
327
|
let selectionPos;
|
|
325
328
|
if (!footnotesSection) {
|
|
326
329
|
const section = state.schema.nodes.footnotes_section.create({}, [
|
|
327
|
-
state.schema.nodes.section_title.create({}, state.schema.text('
|
|
330
|
+
state.schema.nodes.section_title.create({}, state.schema.text('Footnotes')),
|
|
328
331
|
state.schema.nodes.footnotes_element.create({}, footnote),
|
|
329
332
|
]);
|
|
330
333
|
const backmatter = (0, prosemirror_utils_1.findChildrenByType)(tr.doc, transform_1.schema.nodes.backmatter)[0];
|
|
331
|
-
|
|
332
|
-
|
|
334
|
+
const sectionPos = backmatter.pos + 1;
|
|
335
|
+
tr.insert(sectionPos, section);
|
|
336
|
+
let footnotePos = 0;
|
|
337
|
+
section.descendants((n, pos) => {
|
|
338
|
+
if ((0, transform_1.isFootnoteNode)(n)) {
|
|
339
|
+
footnotePos = pos;
|
|
340
|
+
n.descendants((childNode, childPos) => {
|
|
341
|
+
if ((0, transform_1.isParagraphNode)(childNode)) {
|
|
342
|
+
footnotePos += childPos;
|
|
343
|
+
}
|
|
344
|
+
});
|
|
345
|
+
}
|
|
346
|
+
});
|
|
347
|
+
selectionPos = sectionPos + footnotePos;
|
|
333
348
|
}
|
|
334
349
|
else {
|
|
335
350
|
const footnoteElement = (0, prosemirror_utils_1.findChildrenByType)(footnotesSection.node, transform_1.schema.nodes.footnotes_element);
|
|
@@ -341,7 +356,7 @@ const insertInlineFootnote = (kind) => (state, dispatch) => {
|
|
|
341
356
|
selectionPos = pos + 2;
|
|
342
357
|
}
|
|
343
358
|
if (dispatch && selectionPos) {
|
|
344
|
-
const selection = prosemirror_state_1.TextSelection.
|
|
359
|
+
const selection = prosemirror_state_1.TextSelection.near(tr.doc.resolve(selectionPos));
|
|
345
360
|
dispatch(tr.setSelection(selection).scrollIntoView());
|
|
346
361
|
}
|
|
347
362
|
return true;
|
|
@@ -708,10 +723,13 @@ const addBlockComment = (node, state, dispatch) => {
|
|
|
708
723
|
[highlight_1.SET_COMMENT]: comment,
|
|
709
724
|
});
|
|
710
725
|
tr.setMeta('addToHistory', false);
|
|
711
|
-
if (
|
|
712
|
-
dispatch(tr);
|
|
726
|
+
if (isAllowedType(type)) {
|
|
727
|
+
dispatch && dispatch(tr);
|
|
728
|
+
return true;
|
|
729
|
+
}
|
|
730
|
+
else {
|
|
731
|
+
return false;
|
|
713
732
|
}
|
|
714
|
-
return true;
|
|
715
733
|
};
|
|
716
734
|
const addHighlightComment = (node, state, dispatch) => {
|
|
717
735
|
const { attrs: { id }, type, } = node;
|
|
@@ -32,18 +32,24 @@ const createEditorState = (props) => prosemirror_state_1.EditorState.create({
|
|
|
32
32
|
plugins: (0, editor_plugins_1.default)(props),
|
|
33
33
|
});
|
|
34
34
|
exports.createEditorState = createEditorState;
|
|
35
|
-
const createEditorView = (props, root, state, dispatch) =>
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
35
|
+
const createEditorView = (props, root, state, dispatch) => {
|
|
36
|
+
const view = new prosemirror_view_1.EditorView(root, {
|
|
37
|
+
state,
|
|
38
|
+
editable: () => props.getCapabilities().editArticle,
|
|
39
|
+
scrollMargin: {
|
|
40
|
+
top: 100,
|
|
41
|
+
bottom: 100,
|
|
42
|
+
left: 0,
|
|
43
|
+
right: 0,
|
|
44
|
+
},
|
|
45
|
+
dispatchTransaction: dispatch,
|
|
46
|
+
nodeViews: (0, editor_views_1.default)(props, dispatch),
|
|
47
|
+
attributes: props.attributes,
|
|
48
|
+
transformPasted: paste_1.transformPasted,
|
|
49
|
+
});
|
|
50
|
+
const tr = view.state.tr.setMeta('INIT', true);
|
|
51
|
+
const nextState = view.state.apply(tr);
|
|
52
|
+
view.updateState(nextState);
|
|
53
|
+
return view;
|
|
54
|
+
};
|
|
49
55
|
exports.createEditorView = createEditorView;
|
|
@@ -69,7 +69,7 @@ exports.default = (props, dispatch) => {
|
|
|
69
69
|
footnote: (0, footnote_editable_1.default)(props),
|
|
70
70
|
footnotes_element: (0, footnotes_element_1.default)(props),
|
|
71
71
|
inline_equation: (0, inline_equation_editable_1.default)(props),
|
|
72
|
-
inline_footnote: (0, inline_footnote_editable_1.default)(props),
|
|
72
|
+
inline_footnote: (0, inline_footnote_editable_1.default)(props, dispatch),
|
|
73
73
|
keyword: (0, keyword_1.default)(props, dispatch),
|
|
74
74
|
keyword_group: (0, keyword_group_1.default)(props, dispatch),
|
|
75
75
|
link: (0, link_editable_1.default)(props, dispatch),
|
|
@@ -74,6 +74,9 @@ exports.default = () => {
|
|
|
74
74
|
},
|
|
75
75
|
appendTransaction(transactions, oldState, newState) {
|
|
76
76
|
const { indexedAffiliationIds } = exports.affiliationsKey.getState(newState);
|
|
77
|
+
if (!transactions.find((tr) => tr.docChanged)) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
77
80
|
const oldPluginState = exports.affiliationsKey.getState(oldState);
|
|
78
81
|
const { tr } = newState;
|
|
79
82
|
const affiliations = [];
|
|
@@ -54,7 +54,7 @@ exports.default = (props) => {
|
|
|
54
54
|
props: {
|
|
55
55
|
decorations(state) {
|
|
56
56
|
const bib = (0, exports.getBibliographyPluginState)(state);
|
|
57
|
-
return prosemirror_view_1.DecorationSet.create(state.doc, (0, bibliography_utils_1.buildDecorations)(bib, state.doc));
|
|
57
|
+
return prosemirror_view_1.DecorationSet.create(state.doc, bib ? (0, bibliography_utils_1.buildDecorations)(bib, state.doc) : []);
|
|
58
58
|
},
|
|
59
59
|
},
|
|
60
60
|
});
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* limitations under the License.
|
|
16
16
|
*/
|
|
17
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
-
exports.getInlineFootnotes = exports.updateTableInlineFootnoteLabels = exports.orderTableFootnotes = exports.buildTableFootnoteLabels = exports.getNewFootnotePos = exports.findTableInlineFootnoteIds = void 0;
|
|
18
|
+
exports.getAlphaOrderIndices = exports.getInlineFootnotes = exports.updateTableInlineFootnoteLabels = exports.orderTableFootnotes = exports.buildTableFootnoteLabels = exports.getNewFootnotePos = exports.findTableInlineFootnoteIds = void 0;
|
|
19
19
|
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");
|
|
@@ -113,3 +113,35 @@ const getInlineFootnotes = (id, targetNode) => {
|
|
|
113
113
|
return inlineFootnotes;
|
|
114
114
|
};
|
|
115
115
|
exports.getInlineFootnotes = getInlineFootnotes;
|
|
116
|
+
function getAlphaOrderIndices(index) {
|
|
117
|
+
const unicodeInterval = [97, 123];
|
|
118
|
+
const places = unicodeInterval[1] - unicodeInterval[0];
|
|
119
|
+
function getClassCount(n, order) {
|
|
120
|
+
return n * Math.pow(places, order - 1);
|
|
121
|
+
}
|
|
122
|
+
let indices = null;
|
|
123
|
+
for (;;) {
|
|
124
|
+
let current = index;
|
|
125
|
+
let position = 1;
|
|
126
|
+
while (current >= places) {
|
|
127
|
+
current = current / places;
|
|
128
|
+
position++;
|
|
129
|
+
}
|
|
130
|
+
const newIndex = Math.floor(current);
|
|
131
|
+
indices = indices ? indices : new Array(position).fill(0);
|
|
132
|
+
indices.splice(indices.length - position, 1, newIndex);
|
|
133
|
+
index -= getClassCount(newIndex, position);
|
|
134
|
+
if (position === 1) {
|
|
135
|
+
break;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return (indices || [])
|
|
139
|
+
.map((v, i, array) => {
|
|
140
|
+
if (array.length > 1 && i !== array.length - 1) {
|
|
141
|
+
return String.fromCodePoint(v + unicodeInterval[0] - 1);
|
|
142
|
+
}
|
|
143
|
+
return String.fromCodePoint(v + unicodeInterval[0]);
|
|
144
|
+
})
|
|
145
|
+
.join('');
|
|
146
|
+
}
|
|
147
|
+
exports.getAlphaOrderIndices = getAlphaOrderIndices;
|
|
@@ -18,7 +18,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
18
18
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
19
19
|
};
|
|
20
20
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
-
exports.
|
|
21
|
+
exports.buildPluginState = exports.uncitedFootnoteWidget = exports.footnotesKey = void 0;
|
|
22
|
+
const track_changes_plugin_1 = require("@manuscripts/track-changes-plugin");
|
|
22
23
|
const transform_1 = require("@manuscripts/transform");
|
|
23
24
|
const lodash_1 = require("lodash");
|
|
24
25
|
const prosemirror_state_1 = require("prosemirror-state");
|
|
@@ -31,28 +32,10 @@ const ReactSubView_1 = __importDefault(require("../../views/ReactSubView"));
|
|
|
31
32
|
const placeholder_1 = require("../placeholder");
|
|
32
33
|
const footnotes_utils_1 = require("./footnotes-utils");
|
|
33
34
|
exports.footnotesKey = new prosemirror_state_1.PluginKey('footnotes');
|
|
34
|
-
const buildPluginState = (doc) => {
|
|
35
|
-
const nodes = [];
|
|
36
|
-
let index = 0;
|
|
37
|
-
const labels = new Map();
|
|
38
|
-
doc.descendants((node, pos, parentNode) => {
|
|
39
|
-
if ((0, transform_1.isInlineFootnoteNode)(node) &&
|
|
40
|
-
parentNode &&
|
|
41
|
-
parentNode.type !== transform_1.schema.nodes.table_cell &&
|
|
42
|
-
parentNode.type !== transform_1.schema.nodes.table_header) {
|
|
43
|
-
nodes.push([node, pos]);
|
|
44
|
-
node.attrs.rids.forEach((rid) => {
|
|
45
|
-
labels.set(rid, String(++index));
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
|
-
});
|
|
49
|
-
return { nodes, labels };
|
|
50
|
-
};
|
|
51
|
-
exports.buildPluginState = buildPluginState;
|
|
52
35
|
const scrollToInlineFootnote = (rid, view) => {
|
|
53
36
|
view.state.doc.descendants((node, pos) => {
|
|
54
37
|
const footnote = node;
|
|
55
|
-
if (footnote.attrs.rids.includes(rid)) {
|
|
38
|
+
if ((0, transform_1.isInlineFootnoteNode)(node) && footnote.attrs.rids.includes(rid)) {
|
|
56
39
|
const selection = prosemirror_state_1.NodeSelection.create(view.state.doc, pos);
|
|
57
40
|
view.dispatch(view.state.tr.setSelection(selection).scrollIntoView());
|
|
58
41
|
}
|
|
@@ -62,7 +45,7 @@ const labelWidget = (label, id) => (view) => {
|
|
|
62
45
|
const element = document.createElement('span');
|
|
63
46
|
element.className = 'footnote-label';
|
|
64
47
|
element.textContent = label;
|
|
65
|
-
element.addEventListener('
|
|
48
|
+
element.addEventListener('mousedown', () => {
|
|
66
49
|
scrollToInlineFootnote(id, view);
|
|
67
50
|
});
|
|
68
51
|
return element;
|
|
@@ -137,6 +120,39 @@ const deleteFootnoteWidget = (node, props, id, tableElement) => (view, getPos) =
|
|
|
137
120
|
});
|
|
138
121
|
return deleteBtn;
|
|
139
122
|
};
|
|
123
|
+
const buildPluginState = (doc) => {
|
|
124
|
+
const inlineFootnotes = [];
|
|
125
|
+
const footnotes = new Map();
|
|
126
|
+
let footnoteElement;
|
|
127
|
+
doc.descendants((node, pos, parentNode) => {
|
|
128
|
+
if ((0, transform_1.isFootnotesSectionNode)(node)) {
|
|
129
|
+
node.descendants((node, childPos) => {
|
|
130
|
+
if ((0, transform_1.isFootnotesElementNode)(node)) {
|
|
131
|
+
footnoteElement = [node, pos + childPos];
|
|
132
|
+
}
|
|
133
|
+
if ((0, transform_1.isFootnoteNode)(node)) {
|
|
134
|
+
footnotes.set(node.attrs.id, [node, pos + childPos]);
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
if ((0, transform_1.isInlineFootnoteNode)(node) &&
|
|
139
|
+
parentNode &&
|
|
140
|
+
parentNode.type !== transform_1.schema.nodes.table_cell &&
|
|
141
|
+
parentNode.type !== transform_1.schema.nodes.table_header) {
|
|
142
|
+
inlineFootnotes.push([node, pos]);
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
let index = 0;
|
|
146
|
+
const labels = new Map();
|
|
147
|
+
inlineFootnotes.sort((a, b) => a[1] - b[1]);
|
|
148
|
+
inlineFootnotes.forEach(([node]) => {
|
|
149
|
+
node.attrs.rids.forEach((rid) => {
|
|
150
|
+
labels.set(rid, (0, footnotes_utils_1.getAlphaOrderIndices)(index++));
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
return { inlineFootnotes, labels, footnotes, footnoteElement };
|
|
154
|
+
};
|
|
155
|
+
exports.buildPluginState = buildPluginState;
|
|
140
156
|
exports.default = (props) => {
|
|
141
157
|
return new prosemirror_state_1.Plugin({
|
|
142
158
|
key: exports.footnotesKey,
|
|
@@ -145,25 +161,60 @@ exports.default = (props) => {
|
|
|
145
161
|
return (0, exports.buildPluginState)(instance.doc);
|
|
146
162
|
},
|
|
147
163
|
apply(tr, value, oldState, newState) {
|
|
164
|
+
const prevState = exports.footnotesKey.getState(oldState);
|
|
165
|
+
if (!tr.docChanged && prevState) {
|
|
166
|
+
return prevState;
|
|
167
|
+
}
|
|
148
168
|
return (0, exports.buildPluginState)(newState.doc);
|
|
149
169
|
},
|
|
150
170
|
},
|
|
151
171
|
appendTransaction(transactions, oldState, newState) {
|
|
152
|
-
const {
|
|
153
|
-
const {
|
|
154
|
-
|
|
172
|
+
const { inlineFootnotes: oldInlineFootnoteNodes } = exports.footnotesKey.getState(oldState);
|
|
173
|
+
const { inlineFootnotes: inlineFootnoteNodes, footnotes, labels, footnoteElement, } = exports.footnotesKey.getState(newState);
|
|
174
|
+
const prevIds = oldInlineFootnoteNodes.map(([node]) => node.attrs.rids);
|
|
175
|
+
const newIds = inlineFootnoteNodes.map(([node]) => node.attrs.rids);
|
|
176
|
+
const initTransaction = transactions.find((t) => t.getMeta('INIT'));
|
|
177
|
+
if (!footnoteElement || (!initTransaction && (0, lodash_1.isEqual)(prevIds, newIds))) {
|
|
155
178
|
return null;
|
|
156
179
|
}
|
|
157
180
|
const { tr } = newState;
|
|
181
|
+
const footnotesReordered = [];
|
|
182
|
+
const footnotesRest = new Map(footnotes);
|
|
158
183
|
inlineFootnoteNodes.forEach(([node, pos]) => {
|
|
159
184
|
const footnote = node;
|
|
160
185
|
const contents = footnote.attrs.rids
|
|
161
|
-
.map((rid) =>
|
|
186
|
+
.map((rid) => {
|
|
187
|
+
const currentfNode = footnotesRest.get(rid);
|
|
188
|
+
if (currentfNode) {
|
|
189
|
+
footnotesReordered.push(currentfNode[0]);
|
|
190
|
+
footnotesRest.delete(rid);
|
|
191
|
+
}
|
|
192
|
+
return labels.get(rid);
|
|
193
|
+
})
|
|
162
194
|
.join('');
|
|
163
195
|
if (footnote.attrs.contents !== contents) {
|
|
164
196
|
tr.setNodeMarkup(pos, undefined, Object.assign(Object.assign({}, footnote.attrs), { rids: footnote.attrs.rids, contents }));
|
|
165
197
|
}
|
|
166
198
|
});
|
|
199
|
+
footnotesRest.forEach(([node]) => footnotesReordered.push(node));
|
|
200
|
+
const newFElement = transform_1.schema.nodes.footnotes_element.create(footnoteElement[0].attrs, footnotesReordered);
|
|
201
|
+
if (newFElement && footnotes.size > 0) {
|
|
202
|
+
tr.replaceWith(footnoteElement[1], footnoteElement[1] + footnoteElement[0].nodeSize, newFElement);
|
|
203
|
+
}
|
|
204
|
+
const prevSelection = newState.selection;
|
|
205
|
+
const selectedFootnote = (0, prosemirror_utils_1.findParentNodeClosestToPos)(prevSelection.$anchor, (node) => (0, transform_1.isFootnoteNode)(node));
|
|
206
|
+
if (selectedFootnote && footnotes.size > 0) {
|
|
207
|
+
let newFootnotePos = 0;
|
|
208
|
+
for (let i = 0; i < footnotesReordered.length; i++) {
|
|
209
|
+
const node = footnotesReordered[i];
|
|
210
|
+
newFootnotePos += node.nodeSize;
|
|
211
|
+
if (node.attrs.id === selectedFootnote.node.attrs.id) {
|
|
212
|
+
break;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
tr.setSelection(prosemirror_state_1.TextSelection.create(tr.doc, footnoteElement[1] + newFootnotePos));
|
|
216
|
+
}
|
|
217
|
+
(0, track_changes_plugin_1.skipTracking)(tr);
|
|
167
218
|
return tr;
|
|
168
219
|
},
|
|
169
220
|
props: {
|
|
@@ -206,7 +257,7 @@ exports.default = (props) => {
|
|
|
206
257
|
}
|
|
207
258
|
}
|
|
208
259
|
if (!((_a = node.firstChild) === null || _a === void 0 ? void 0 : _a.textContent)) {
|
|
209
|
-
decorations.push(prosemirror_view_1.Decoration.widget(pos + 2, (0, placeholder_1.placeholderWidget)('
|
|
260
|
+
decorations.push(prosemirror_view_1.Decoration.widget(pos + 2, (0, placeholder_1.placeholderWidget)('Type new footnote here')));
|
|
210
261
|
}
|
|
211
262
|
if (tableInlineFootnoteIds &&
|
|
212
263
|
!tableInlineFootnoteIds.has(node.attrs.id)) {
|
|
@@ -62,12 +62,13 @@ exports.default = (props) => {
|
|
|
62
62
|
key: exports.highlightKey,
|
|
63
63
|
state: {
|
|
64
64
|
init: (tr, state) => buildPluginState(state.doc),
|
|
65
|
-
apply: (tr) => {
|
|
65
|
+
apply: (tr, value) => {
|
|
66
66
|
const meta = tr.getMeta(exports.highlightKey);
|
|
67
|
-
if (meta) {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
67
|
+
if (meta && exports.SET_COMMENT in meta) {
|
|
68
|
+
props.setComment(meta[exports.SET_COMMENT]);
|
|
69
|
+
}
|
|
70
|
+
else if (!tr.docChanged || tr.step.length === 0) {
|
|
71
|
+
return value;
|
|
71
72
|
}
|
|
72
73
|
return buildPluginState(tr.doc);
|
|
73
74
|
},
|
|
@@ -94,7 +94,6 @@ exports.default = (props) => new prosemirror_state_1.Plugin({
|
|
|
94
94
|
return buildSelectedSuggestionDecoration(suggestionId, state, props);
|
|
95
95
|
}
|
|
96
96
|
if (tr.getMeta(exports.CLEAR_SUGGESTION_ID)) {
|
|
97
|
-
props.setEditorSelectedSuggestion(undefined);
|
|
98
97
|
return prosemirror_view_1.DecorationSet.empty;
|
|
99
98
|
}
|
|
100
99
|
return value;
|
|
@@ -105,8 +104,11 @@ exports.default = (props) => new prosemirror_state_1.Plugin({
|
|
|
105
104
|
const nodeClicked = view.state.doc.nodeAt(pos);
|
|
106
105
|
const trackChangesData = nodeClicked && getTrackChangesData(nodeClicked);
|
|
107
106
|
if (!trackChangesData) {
|
|
108
|
-
|
|
109
|
-
|
|
107
|
+
setTimeout(() => {
|
|
108
|
+
const newTr = view.state.tr.setMeta(exports.CLEAR_SUGGESTION_ID, true);
|
|
109
|
+
view.dispatch(newTr);
|
|
110
|
+
props.setEditorSelectedSuggestion(undefined);
|
|
111
|
+
});
|
|
110
112
|
}
|
|
111
113
|
},
|
|
112
114
|
decorations: (state) => exports.selectedSuggestionKey.getState(state),
|
|
@@ -122,7 +124,9 @@ const buildSelectedSuggestionDecoration = (suggestionId, state, props) => {
|
|
|
122
124
|
decorations.push(decoration(change.from, change.to, {
|
|
123
125
|
class: 'selected-suggestion',
|
|
124
126
|
}));
|
|
125
|
-
|
|
127
|
+
setTimeout(() => {
|
|
128
|
+
props.setEditorSelectedSuggestion(change.id);
|
|
129
|
+
}, 0);
|
|
126
130
|
}
|
|
127
131
|
return prosemirror_view_1.DecorationSet.create(state.doc, decorations);
|
|
128
132
|
};
|
|
@@ -14,6 +14,9 @@ const isInlineFootnoteChange = (step, oldState, newState) => {
|
|
|
14
14
|
exports.default = () => {
|
|
15
15
|
return new prosemirror_state_1.Plugin({
|
|
16
16
|
appendTransaction(transactions, oldState, newState) {
|
|
17
|
+
if (!transactions.find((tr) => tr.docChanged)) {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
17
20
|
const tableInlineFootnoteChange = transactions.find((tr) => tr.steps.find((s, i) => {
|
|
18
21
|
var _a;
|
|
19
22
|
if (s instanceof prosemirror_transform_1.ReplaceStep) {
|
|
@@ -62,7 +62,7 @@ class BaseNodeView {
|
|
|
62
62
|
}
|
|
63
63
|
};
|
|
64
64
|
}
|
|
65
|
-
setDomAttrs(node, element, omit = []) {
|
|
65
|
+
setDomAttrs(node, element, omit = ['contents']) {
|
|
66
66
|
Object.keys(node.attrs || {}).forEach((attr) => {
|
|
67
67
|
if (!omit.includes(attr)) {
|
|
68
68
|
element.setAttribute(attr, node.attrs[attr]);
|
|
@@ -49,6 +49,9 @@ class BibliographyElementBlockView extends block_view_1.default {
|
|
|
49
49
|
this.showPopper = (id) => {
|
|
50
50
|
this.props.popper.destroy();
|
|
51
51
|
const bib = (0, bibliography_1.getBibliographyPluginState)(this.view.state);
|
|
52
|
+
if (!bib) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
52
55
|
const componentProps = {
|
|
53
56
|
items: Array.from(bib.bibliographyItems.values()),
|
|
54
57
|
citationCounts: bib.citationCounts,
|
|
@@ -140,6 +143,9 @@ class BibliographyElementBlockView extends block_view_1.default {
|
|
|
140
143
|
const can = this.props.getCapabilities();
|
|
141
144
|
const wrapper = document.createElement('div');
|
|
142
145
|
wrapper.classList.add('contents');
|
|
146
|
+
if (!bib) {
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
143
149
|
const [meta, bibliography] = bib.provider.makeBibliography();
|
|
144
150
|
for (let i = 0; i < bibliography.length; i++) {
|
|
145
151
|
const id = meta.entry_ids[i];
|
|
@@ -40,6 +40,9 @@ class CitationView extends base_node_view_1.BaseNodeView {
|
|
|
40
40
|
};
|
|
41
41
|
this.updateContents = () => {
|
|
42
42
|
const bib = (0, bibliography_1.getBibliographyPluginState)(this.view.state);
|
|
43
|
+
if (!bib) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
43
46
|
const classes = [
|
|
44
47
|
'citation',
|
|
45
48
|
...(0, track_changes_utils_1.getChangeClasses)(this.node.attrs.dataTracked),
|
|
@@ -90,6 +90,9 @@ class CitationEditableView extends citation_1.CitationView {
|
|
|
90
90
|
this.showPopper = () => {
|
|
91
91
|
this.props.popper.destroy();
|
|
92
92
|
const bib = (0, bibliography_1.getBibliographyPluginState)(this.view.state);
|
|
93
|
+
if (!bib) {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
93
96
|
const can = this.props.getCapabilities();
|
|
94
97
|
const attrs = (0, track_changes_utils_1.getActualAttrs)(this.node);
|
|
95
98
|
const rids = attrs.rids;
|
|
@@ -152,6 +155,9 @@ class CitationEditableView extends citation_1.CitationView {
|
|
|
152
155
|
};
|
|
153
156
|
this.handleCite = (items) => {
|
|
154
157
|
const bib = (0, bibliography_1.getBibliographyPluginState)(this.view.state);
|
|
158
|
+
if (!bib) {
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
155
161
|
const attrs = (0, track_changes_utils_1.getActualAttrs)(this.node);
|
|
156
162
|
const rids = [...attrs.rids];
|
|
157
163
|
items = items.filter((i) => !rids.includes(i.id));
|
|
@@ -28,7 +28,9 @@ class FootnotesElementView extends block_view_1.default {
|
|
|
28
28
|
this.elementType = 'div';
|
|
29
29
|
this.checkEditability = () => {
|
|
30
30
|
var _a, _b;
|
|
31
|
-
const editable = this.node.childCount
|
|
31
|
+
const editable = this.props.getCapabilities().editArticle && this.node.childCount
|
|
32
|
+
? 'true'
|
|
33
|
+
: 'false';
|
|
32
34
|
(_a = this.contentDOM) === null || _a === void 0 ? void 0 : _a.setAttribute('contenteditable', editable);
|
|
33
35
|
(_b = this.dom) === null || _b === void 0 ? void 0 : _b.setAttribute('contenteditable', editable);
|
|
34
36
|
};
|
|
@@ -21,6 +21,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
21
21
|
exports.InlineFootnoteView = void 0;
|
|
22
22
|
const style_guide_1 = require("@manuscripts/style-guide");
|
|
23
23
|
const transform_1 = require("@manuscripts/transform");
|
|
24
|
+
const prosemirror_state_1 = require("prosemirror-state");
|
|
24
25
|
const prosemirror_utils_1 = require("prosemirror-utils");
|
|
25
26
|
const commands_1 = require("../commands");
|
|
26
27
|
const track_changes_utils_1 = require("../lib/track-changes-utils");
|
|
@@ -33,6 +34,7 @@ class InlineFootnoteView extends base_node_view_1.BaseNodeView {
|
|
|
33
34
|
super(...arguments);
|
|
34
35
|
this.findParentTableElement = () => (0, prosemirror_utils_1.findParentNodeClosestToPos)(this.view.state.doc.resolve(this.getPos()), (node) => node.type === transform_1.schema.nodes.table_element);
|
|
35
36
|
this.handleClick = () => {
|
|
37
|
+
var _a;
|
|
36
38
|
if ((0, track_changes_utils_1.isDeleted)(this.node)) {
|
|
37
39
|
return;
|
|
38
40
|
}
|
|
@@ -49,11 +51,24 @@ class InlineFootnoteView extends base_node_view_1.BaseNodeView {
|
|
|
49
51
|
this.props.popper.show(this.dom, this.popperContainer, 'bottom-end');
|
|
50
52
|
}
|
|
51
53
|
else {
|
|
52
|
-
|
|
54
|
+
if ((_a = this.node.attrs.rids) === null || _a === void 0 ? void 0 : _a.length) {
|
|
55
|
+
let nodePos = undefined;
|
|
56
|
+
this.view.state.doc.descendants((node, pos) => {
|
|
57
|
+
if (node.attrs.id === this.node.attrs.rids[0]) {
|
|
58
|
+
nodePos = pos;
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
if (nodePos && this.props.dispatch) {
|
|
62
|
+
const sel = prosemirror_state_1.TextSelection.near(this.view.state.doc.resolve(nodePos + 1));
|
|
63
|
+
this.props.dispatch(this.view.state.tr.setSelection(sel).scrollIntoView());
|
|
64
|
+
}
|
|
65
|
+
}
|
|
53
66
|
}
|
|
54
67
|
};
|
|
55
68
|
this.updateContents = () => {
|
|
56
|
-
|
|
69
|
+
const node = this.node;
|
|
70
|
+
this.dom.setAttribute('rids', node.attrs.rids.join(','));
|
|
71
|
+
this.dom.setAttribute('contents', node.attrs.contents);
|
|
57
72
|
this.dom.className = [
|
|
58
73
|
'footnote',
|
|
59
74
|
...(0, track_changes_utils_1.getChangeClasses)(this.node.attrs.dataTracked),
|
package/dist/es/commands.js
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
*/
|
|
16
16
|
import { ObjectTypes } from '@manuscripts/json-schema';
|
|
17
17
|
import { skipTracking } from '@manuscripts/track-changes-plugin';
|
|
18
|
-
import { buildComment, generateID, isElementNodeType, isInBibliographySection, isListNode, isSectionNodeType, schema, } from '@manuscripts/transform';
|
|
18
|
+
import { buildComment, generateID, isElementNodeType, isFootnoteNode, isInBibliographySection, isListNode, isParagraphNode, isSectionNodeType, schema, } from '@manuscripts/transform';
|
|
19
19
|
import { NodeRange } from 'prosemirror-model';
|
|
20
20
|
import { wrapInList } from 'prosemirror-schema-list';
|
|
21
21
|
import { NodeSelection, TextSelection, } from 'prosemirror-state';
|
|
@@ -53,7 +53,10 @@ export const blockActive = (type) => (state) => {
|
|
|
53
53
|
return false;
|
|
54
54
|
};
|
|
55
55
|
export const canInsert = (type) => (state) => {
|
|
56
|
-
const { $from } = state.selection;
|
|
56
|
+
const { $from, $to } = state.selection;
|
|
57
|
+
if ($from.node().type === schema.nodes.title && $from.pos === $to.pos) {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
57
60
|
for (let d = $from.depth; d >= 0; d--) {
|
|
58
61
|
const index = $from.index(d);
|
|
59
62
|
if ($from.node(d).canReplaceWith(index, index, type)) {
|
|
@@ -305,12 +308,24 @@ export const insertInlineFootnote = (kind) => (state, dispatch) => {
|
|
|
305
308
|
let selectionPos;
|
|
306
309
|
if (!footnotesSection) {
|
|
307
310
|
const section = state.schema.nodes.footnotes_section.create({}, [
|
|
308
|
-
state.schema.nodes.section_title.create({}, state.schema.text('
|
|
311
|
+
state.schema.nodes.section_title.create({}, state.schema.text('Footnotes')),
|
|
309
312
|
state.schema.nodes.footnotes_element.create({}, footnote),
|
|
310
313
|
]);
|
|
311
314
|
const backmatter = findChildrenByType(tr.doc, schema.nodes.backmatter)[0];
|
|
312
|
-
|
|
313
|
-
|
|
315
|
+
const sectionPos = backmatter.pos + 1;
|
|
316
|
+
tr.insert(sectionPos, section);
|
|
317
|
+
let footnotePos = 0;
|
|
318
|
+
section.descendants((n, pos) => {
|
|
319
|
+
if (isFootnoteNode(n)) {
|
|
320
|
+
footnotePos = pos;
|
|
321
|
+
n.descendants((childNode, childPos) => {
|
|
322
|
+
if (isParagraphNode(childNode)) {
|
|
323
|
+
footnotePos += childPos;
|
|
324
|
+
}
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
});
|
|
328
|
+
selectionPos = sectionPos + footnotePos;
|
|
314
329
|
}
|
|
315
330
|
else {
|
|
316
331
|
const footnoteElement = findChildrenByType(footnotesSection.node, schema.nodes.footnotes_element);
|
|
@@ -322,7 +337,7 @@ export const insertInlineFootnote = (kind) => (state, dispatch) => {
|
|
|
322
337
|
selectionPos = pos + 2;
|
|
323
338
|
}
|
|
324
339
|
if (dispatch && selectionPos) {
|
|
325
|
-
const selection = TextSelection.
|
|
340
|
+
const selection = TextSelection.near(tr.doc.resolve(selectionPos));
|
|
326
341
|
dispatch(tr.setSelection(selection).scrollIntoView());
|
|
327
342
|
}
|
|
328
343
|
return true;
|
|
@@ -671,10 +686,13 @@ const addBlockComment = (node, state, dispatch) => {
|
|
|
671
686
|
[SET_COMMENT]: comment,
|
|
672
687
|
});
|
|
673
688
|
tr.setMeta('addToHistory', false);
|
|
674
|
-
if (
|
|
675
|
-
dispatch(tr);
|
|
689
|
+
if (isAllowedType(type)) {
|
|
690
|
+
dispatch && dispatch(tr);
|
|
691
|
+
return true;
|
|
692
|
+
}
|
|
693
|
+
else {
|
|
694
|
+
return false;
|
|
676
695
|
}
|
|
677
|
-
return true;
|
|
678
696
|
};
|
|
679
697
|
const addHighlightComment = (node, state, dispatch) => {
|
|
680
698
|
const { attrs: { id }, type, } = node;
|
|
@@ -25,17 +25,23 @@ export const createEditorState = (props) => EditorState.create({
|
|
|
25
25
|
schema,
|
|
26
26
|
plugins: plugins(props),
|
|
27
27
|
});
|
|
28
|
-
export const createEditorView = (props, root, state, dispatch) =>
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
28
|
+
export const createEditorView = (props, root, state, dispatch) => {
|
|
29
|
+
const view = new EditorView(root, {
|
|
30
|
+
state,
|
|
31
|
+
editable: () => props.getCapabilities().editArticle,
|
|
32
|
+
scrollMargin: {
|
|
33
|
+
top: 100,
|
|
34
|
+
bottom: 100,
|
|
35
|
+
left: 0,
|
|
36
|
+
right: 0,
|
|
37
|
+
},
|
|
38
|
+
dispatchTransaction: dispatch,
|
|
39
|
+
nodeViews: views(props, dispatch),
|
|
40
|
+
attributes: props.attributes,
|
|
41
|
+
transformPasted,
|
|
42
|
+
});
|
|
43
|
+
const tr = view.state.tr.setMeta('INIT', true);
|
|
44
|
+
const nextState = view.state.apply(tr);
|
|
45
|
+
view.updateState(nextState);
|
|
46
|
+
return view;
|
|
47
|
+
};
|
|
@@ -64,7 +64,7 @@ export default (props, dispatch) => {
|
|
|
64
64
|
footnote: footnote(props),
|
|
65
65
|
footnotes_element: footnotesElement(props),
|
|
66
66
|
inline_equation: inlineEquation(props),
|
|
67
|
-
inline_footnote: inlineFootnote(props),
|
|
67
|
+
inline_footnote: inlineFootnote(props, dispatch),
|
|
68
68
|
keyword: keyword(props, dispatch),
|
|
69
69
|
keyword_group: keywordGroup(props, dispatch),
|
|
70
70
|
link: link(props, dispatch),
|
|
@@ -70,6 +70,9 @@ export default () => {
|
|
|
70
70
|
},
|
|
71
71
|
appendTransaction(transactions, oldState, newState) {
|
|
72
72
|
const { indexedAffiliationIds } = affiliationsKey.getState(newState);
|
|
73
|
+
if (!transactions.find((tr) => tr.docChanged)) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
73
76
|
const oldPluginState = affiliationsKey.getState(oldState);
|
|
74
77
|
const { tr } = newState;
|
|
75
78
|
const affiliations = [];
|
|
@@ -51,7 +51,7 @@ export default (props) => {
|
|
|
51
51
|
props: {
|
|
52
52
|
decorations(state) {
|
|
53
53
|
const bib = getBibliographyPluginState(state);
|
|
54
|
-
return DecorationSet.create(state.doc, buildDecorations(bib, state.doc));
|
|
54
|
+
return DecorationSet.create(state.doc, bib ? buildDecorations(bib, state.doc) : []);
|
|
55
55
|
},
|
|
56
56
|
},
|
|
57
57
|
});
|
|
@@ -104,3 +104,34 @@ export const getInlineFootnotes = (id, targetNode) => {
|
|
|
104
104
|
});
|
|
105
105
|
return inlineFootnotes;
|
|
106
106
|
};
|
|
107
|
+
export function getAlphaOrderIndices(index) {
|
|
108
|
+
const unicodeInterval = [97, 123];
|
|
109
|
+
const places = unicodeInterval[1] - unicodeInterval[0];
|
|
110
|
+
function getClassCount(n, order) {
|
|
111
|
+
return n * Math.pow(places, order - 1);
|
|
112
|
+
}
|
|
113
|
+
let indices = null;
|
|
114
|
+
for (;;) {
|
|
115
|
+
let current = index;
|
|
116
|
+
let position = 1;
|
|
117
|
+
while (current >= places) {
|
|
118
|
+
current = current / places;
|
|
119
|
+
position++;
|
|
120
|
+
}
|
|
121
|
+
const newIndex = Math.floor(current);
|
|
122
|
+
indices = indices ? indices : new Array(position).fill(0);
|
|
123
|
+
indices.splice(indices.length - position, 1, newIndex);
|
|
124
|
+
index -= getClassCount(newIndex, position);
|
|
125
|
+
if (position === 1) {
|
|
126
|
+
break;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return (indices || [])
|
|
130
|
+
.map((v, i, array) => {
|
|
131
|
+
if (array.length > 1 && i !== array.length - 1) {
|
|
132
|
+
return String.fromCodePoint(v + unicodeInterval[0] - 1);
|
|
133
|
+
}
|
|
134
|
+
return String.fromCodePoint(v + unicodeInterval[0]);
|
|
135
|
+
})
|
|
136
|
+
.join('');
|
|
137
|
+
}
|
|
@@ -13,9 +13,10 @@
|
|
|
13
13
|
* See the License for the specific language governing permissions and
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
|
-
import {
|
|
16
|
+
import { skipTracking } from '@manuscripts/track-changes-plugin';
|
|
17
|
+
import { isFootnoteNode, isFootnotesElementNode, isFootnotesSectionNode, isInlineFootnoteNode, schema, } from '@manuscripts/transform';
|
|
17
18
|
import { isEqual } from 'lodash';
|
|
18
|
-
import { NodeSelection, Plugin, PluginKey } from 'prosemirror-state';
|
|
19
|
+
import { NodeSelection, Plugin, PluginKey, TextSelection, } from 'prosemirror-state';
|
|
19
20
|
import { findParentNodeClosestToPos, findParentNodeOfType, } from 'prosemirror-utils';
|
|
20
21
|
import { Decoration, DecorationSet } from 'prosemirror-view';
|
|
21
22
|
import { alertIcon, deleteIcon } from '../../assets';
|
|
@@ -23,29 +24,12 @@ import { DeleteFootnoteDialog, } from '../../components/views/DeleteFootnoteDial
|
|
|
23
24
|
import { findParentNodeWithIdValue, getChildOfType } from '../../lib/utils';
|
|
24
25
|
import ReactSubView from '../../views/ReactSubView';
|
|
25
26
|
import { placeholderWidget } from '../placeholder';
|
|
26
|
-
import { findTableInlineFootnoteIds, getInlineFootnotes, } from './footnotes-utils';
|
|
27
|
+
import { findTableInlineFootnoteIds, getAlphaOrderIndices, getInlineFootnotes, } from './footnotes-utils';
|
|
27
28
|
export const footnotesKey = new PluginKey('footnotes');
|
|
28
|
-
export const buildPluginState = (doc) => {
|
|
29
|
-
const nodes = [];
|
|
30
|
-
let index = 0;
|
|
31
|
-
const labels = new Map();
|
|
32
|
-
doc.descendants((node, pos, parentNode) => {
|
|
33
|
-
if (isInlineFootnoteNode(node) &&
|
|
34
|
-
parentNode &&
|
|
35
|
-
parentNode.type !== schema.nodes.table_cell &&
|
|
36
|
-
parentNode.type !== schema.nodes.table_header) {
|
|
37
|
-
nodes.push([node, pos]);
|
|
38
|
-
node.attrs.rids.forEach((rid) => {
|
|
39
|
-
labels.set(rid, String(++index));
|
|
40
|
-
});
|
|
41
|
-
}
|
|
42
|
-
});
|
|
43
|
-
return { nodes, labels };
|
|
44
|
-
};
|
|
45
29
|
const scrollToInlineFootnote = (rid, view) => {
|
|
46
30
|
view.state.doc.descendants((node, pos) => {
|
|
47
31
|
const footnote = node;
|
|
48
|
-
if (footnote.attrs.rids.includes(rid)) {
|
|
32
|
+
if (isInlineFootnoteNode(node) && footnote.attrs.rids.includes(rid)) {
|
|
49
33
|
const selection = NodeSelection.create(view.state.doc, pos);
|
|
50
34
|
view.dispatch(view.state.tr.setSelection(selection).scrollIntoView());
|
|
51
35
|
}
|
|
@@ -55,7 +39,7 @@ const labelWidget = (label, id) => (view) => {
|
|
|
55
39
|
const element = document.createElement('span');
|
|
56
40
|
element.className = 'footnote-label';
|
|
57
41
|
element.textContent = label;
|
|
58
|
-
element.addEventListener('
|
|
42
|
+
element.addEventListener('mousedown', () => {
|
|
59
43
|
scrollToInlineFootnote(id, view);
|
|
60
44
|
});
|
|
61
45
|
return element;
|
|
@@ -129,6 +113,38 @@ const deleteFootnoteWidget = (node, props, id, tableElement) => (view, getPos) =
|
|
|
129
113
|
});
|
|
130
114
|
return deleteBtn;
|
|
131
115
|
};
|
|
116
|
+
export const buildPluginState = (doc) => {
|
|
117
|
+
const inlineFootnotes = [];
|
|
118
|
+
const footnotes = new Map();
|
|
119
|
+
let footnoteElement;
|
|
120
|
+
doc.descendants((node, pos, parentNode) => {
|
|
121
|
+
if (isFootnotesSectionNode(node)) {
|
|
122
|
+
node.descendants((node, childPos) => {
|
|
123
|
+
if (isFootnotesElementNode(node)) {
|
|
124
|
+
footnoteElement = [node, pos + childPos];
|
|
125
|
+
}
|
|
126
|
+
if (isFootnoteNode(node)) {
|
|
127
|
+
footnotes.set(node.attrs.id, [node, pos + childPos]);
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
if (isInlineFootnoteNode(node) &&
|
|
132
|
+
parentNode &&
|
|
133
|
+
parentNode.type !== schema.nodes.table_cell &&
|
|
134
|
+
parentNode.type !== schema.nodes.table_header) {
|
|
135
|
+
inlineFootnotes.push([node, pos]);
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
let index = 0;
|
|
139
|
+
const labels = new Map();
|
|
140
|
+
inlineFootnotes.sort((a, b) => a[1] - b[1]);
|
|
141
|
+
inlineFootnotes.forEach(([node]) => {
|
|
142
|
+
node.attrs.rids.forEach((rid) => {
|
|
143
|
+
labels.set(rid, getAlphaOrderIndices(index++));
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
return { inlineFootnotes, labels, footnotes, footnoteElement };
|
|
147
|
+
};
|
|
132
148
|
export default (props) => {
|
|
133
149
|
return new Plugin({
|
|
134
150
|
key: footnotesKey,
|
|
@@ -137,25 +153,60 @@ export default (props) => {
|
|
|
137
153
|
return buildPluginState(instance.doc);
|
|
138
154
|
},
|
|
139
155
|
apply(tr, value, oldState, newState) {
|
|
156
|
+
const prevState = footnotesKey.getState(oldState);
|
|
157
|
+
if (!tr.docChanged && prevState) {
|
|
158
|
+
return prevState;
|
|
159
|
+
}
|
|
140
160
|
return buildPluginState(newState.doc);
|
|
141
161
|
},
|
|
142
162
|
},
|
|
143
163
|
appendTransaction(transactions, oldState, newState) {
|
|
144
|
-
const {
|
|
145
|
-
const {
|
|
146
|
-
|
|
164
|
+
const { inlineFootnotes: oldInlineFootnoteNodes } = footnotesKey.getState(oldState);
|
|
165
|
+
const { inlineFootnotes: inlineFootnoteNodes, footnotes, labels, footnoteElement, } = footnotesKey.getState(newState);
|
|
166
|
+
const prevIds = oldInlineFootnoteNodes.map(([node]) => node.attrs.rids);
|
|
167
|
+
const newIds = inlineFootnoteNodes.map(([node]) => node.attrs.rids);
|
|
168
|
+
const initTransaction = transactions.find((t) => t.getMeta('INIT'));
|
|
169
|
+
if (!footnoteElement || (!initTransaction && isEqual(prevIds, newIds))) {
|
|
147
170
|
return null;
|
|
148
171
|
}
|
|
149
172
|
const { tr } = newState;
|
|
173
|
+
const footnotesReordered = [];
|
|
174
|
+
const footnotesRest = new Map(footnotes);
|
|
150
175
|
inlineFootnoteNodes.forEach(([node, pos]) => {
|
|
151
176
|
const footnote = node;
|
|
152
177
|
const contents = footnote.attrs.rids
|
|
153
|
-
.map((rid) =>
|
|
178
|
+
.map((rid) => {
|
|
179
|
+
const currentfNode = footnotesRest.get(rid);
|
|
180
|
+
if (currentfNode) {
|
|
181
|
+
footnotesReordered.push(currentfNode[0]);
|
|
182
|
+
footnotesRest.delete(rid);
|
|
183
|
+
}
|
|
184
|
+
return labels.get(rid);
|
|
185
|
+
})
|
|
154
186
|
.join('');
|
|
155
187
|
if (footnote.attrs.contents !== contents) {
|
|
156
188
|
tr.setNodeMarkup(pos, undefined, Object.assign(Object.assign({}, footnote.attrs), { rids: footnote.attrs.rids, contents }));
|
|
157
189
|
}
|
|
158
190
|
});
|
|
191
|
+
footnotesRest.forEach(([node]) => footnotesReordered.push(node));
|
|
192
|
+
const newFElement = schema.nodes.footnotes_element.create(footnoteElement[0].attrs, footnotesReordered);
|
|
193
|
+
if (newFElement && footnotes.size > 0) {
|
|
194
|
+
tr.replaceWith(footnoteElement[1], footnoteElement[1] + footnoteElement[0].nodeSize, newFElement);
|
|
195
|
+
}
|
|
196
|
+
const prevSelection = newState.selection;
|
|
197
|
+
const selectedFootnote = findParentNodeClosestToPos(prevSelection.$anchor, (node) => isFootnoteNode(node));
|
|
198
|
+
if (selectedFootnote && footnotes.size > 0) {
|
|
199
|
+
let newFootnotePos = 0;
|
|
200
|
+
for (let i = 0; i < footnotesReordered.length; i++) {
|
|
201
|
+
const node = footnotesReordered[i];
|
|
202
|
+
newFootnotePos += node.nodeSize;
|
|
203
|
+
if (node.attrs.id === selectedFootnote.node.attrs.id) {
|
|
204
|
+
break;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
tr.setSelection(TextSelection.create(tr.doc, footnoteElement[1] + newFootnotePos));
|
|
208
|
+
}
|
|
209
|
+
skipTracking(tr);
|
|
159
210
|
return tr;
|
|
160
211
|
},
|
|
161
212
|
props: {
|
|
@@ -198,7 +249,7 @@ export default (props) => {
|
|
|
198
249
|
}
|
|
199
250
|
}
|
|
200
251
|
if (!((_a = node.firstChild) === null || _a === void 0 ? void 0 : _a.textContent)) {
|
|
201
|
-
decorations.push(Decoration.widget(pos + 2, placeholderWidget('
|
|
252
|
+
decorations.push(Decoration.widget(pos + 2, placeholderWidget('Type new footnote here')));
|
|
202
253
|
}
|
|
203
254
|
if (tableInlineFootnoteIds &&
|
|
204
255
|
!tableInlineFootnoteIds.has(node.attrs.id)) {
|
|
@@ -56,12 +56,13 @@ export default (props) => {
|
|
|
56
56
|
key: highlightKey,
|
|
57
57
|
state: {
|
|
58
58
|
init: (tr, state) => buildPluginState(state.doc),
|
|
59
|
-
apply: (tr) => {
|
|
59
|
+
apply: (tr, value) => {
|
|
60
60
|
const meta = tr.getMeta(highlightKey);
|
|
61
|
-
if (meta) {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
61
|
+
if (meta && SET_COMMENT in meta) {
|
|
62
|
+
props.setComment(meta[SET_COMMENT]);
|
|
63
|
+
}
|
|
64
|
+
else if (!tr.docChanged || tr.step.length === 0) {
|
|
65
|
+
return value;
|
|
65
66
|
}
|
|
66
67
|
return buildPluginState(tr.doc);
|
|
67
68
|
},
|
|
@@ -91,7 +91,6 @@ export default (props) => new Plugin({
|
|
|
91
91
|
return buildSelectedSuggestionDecoration(suggestionId, state, props);
|
|
92
92
|
}
|
|
93
93
|
if (tr.getMeta(CLEAR_SUGGESTION_ID)) {
|
|
94
|
-
props.setEditorSelectedSuggestion(undefined);
|
|
95
94
|
return DecorationSet.empty;
|
|
96
95
|
}
|
|
97
96
|
return value;
|
|
@@ -102,8 +101,11 @@ export default (props) => new Plugin({
|
|
|
102
101
|
const nodeClicked = view.state.doc.nodeAt(pos);
|
|
103
102
|
const trackChangesData = nodeClicked && getTrackChangesData(nodeClicked);
|
|
104
103
|
if (!trackChangesData) {
|
|
105
|
-
|
|
106
|
-
|
|
104
|
+
setTimeout(() => {
|
|
105
|
+
const newTr = view.state.tr.setMeta(CLEAR_SUGGESTION_ID, true);
|
|
106
|
+
view.dispatch(newTr);
|
|
107
|
+
props.setEditorSelectedSuggestion(undefined);
|
|
108
|
+
});
|
|
107
109
|
}
|
|
108
110
|
},
|
|
109
111
|
decorations: (state) => selectedSuggestionKey.getState(state),
|
|
@@ -119,7 +121,9 @@ const buildSelectedSuggestionDecoration = (suggestionId, state, props) => {
|
|
|
119
121
|
decorations.push(decoration(change.from, change.to, {
|
|
120
122
|
class: 'selected-suggestion',
|
|
121
123
|
}));
|
|
122
|
-
|
|
124
|
+
setTimeout(() => {
|
|
125
|
+
props.setEditorSelectedSuggestion(change.id);
|
|
126
|
+
}, 0);
|
|
123
127
|
}
|
|
124
128
|
return DecorationSet.create(state.doc, decorations);
|
|
125
129
|
};
|
|
@@ -12,6 +12,9 @@ const isInlineFootnoteChange = (step, oldState, newState) => {
|
|
|
12
12
|
export default () => {
|
|
13
13
|
return new Plugin({
|
|
14
14
|
appendTransaction(transactions, oldState, newState) {
|
|
15
|
+
if (!transactions.find((tr) => tr.docChanged)) {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
15
18
|
const tableInlineFootnoteChange = transactions.find((tr) => tr.steps.find((s, i) => {
|
|
16
19
|
var _a;
|
|
17
20
|
if (s instanceof ReplaceStep) {
|
|
@@ -59,7 +59,7 @@ export class BaseNodeView {
|
|
|
59
59
|
}
|
|
60
60
|
};
|
|
61
61
|
}
|
|
62
|
-
setDomAttrs(node, element, omit = []) {
|
|
62
|
+
setDomAttrs(node, element, omit = ['contents']) {
|
|
63
63
|
Object.keys(node.attrs || {}).forEach((attr) => {
|
|
64
64
|
if (!omit.includes(attr)) {
|
|
65
65
|
element.setAttribute(attr, node.attrs[attr]);
|
|
@@ -43,6 +43,9 @@ export class BibliographyElementBlockView extends BlockView {
|
|
|
43
43
|
this.showPopper = (id) => {
|
|
44
44
|
this.props.popper.destroy();
|
|
45
45
|
const bib = getBibliographyPluginState(this.view.state);
|
|
46
|
+
if (!bib) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
46
49
|
const componentProps = {
|
|
47
50
|
items: Array.from(bib.bibliographyItems.values()),
|
|
48
51
|
citationCounts: bib.citationCounts,
|
|
@@ -134,6 +137,9 @@ export class BibliographyElementBlockView extends BlockView {
|
|
|
134
137
|
const can = this.props.getCapabilities();
|
|
135
138
|
const wrapper = document.createElement('div');
|
|
136
139
|
wrapper.classList.add('contents');
|
|
140
|
+
if (!bib) {
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
137
143
|
const [meta, bibliography] = bib.provider.makeBibliography();
|
|
138
144
|
for (let i = 0; i < bibliography.length; i++) {
|
|
139
145
|
const id = meta.entry_ids[i];
|
|
@@ -37,6 +37,9 @@ export class CitationView extends BaseNodeView {
|
|
|
37
37
|
};
|
|
38
38
|
this.updateContents = () => {
|
|
39
39
|
const bib = getBibliographyPluginState(this.view.state);
|
|
40
|
+
if (!bib) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
40
43
|
const classes = [
|
|
41
44
|
'citation',
|
|
42
45
|
...getChangeClasses(this.node.attrs.dataTracked),
|
|
@@ -84,6 +84,9 @@ export class CitationEditableView extends CitationView {
|
|
|
84
84
|
this.showPopper = () => {
|
|
85
85
|
this.props.popper.destroy();
|
|
86
86
|
const bib = getBibliographyPluginState(this.view.state);
|
|
87
|
+
if (!bib) {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
87
90
|
const can = this.props.getCapabilities();
|
|
88
91
|
const attrs = getActualAttrs(this.node);
|
|
89
92
|
const rids = attrs.rids;
|
|
@@ -146,6 +149,9 @@ export class CitationEditableView extends CitationView {
|
|
|
146
149
|
};
|
|
147
150
|
this.handleCite = (items) => {
|
|
148
151
|
const bib = getBibliographyPluginState(this.view.state);
|
|
152
|
+
if (!bib) {
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
149
155
|
const attrs = getActualAttrs(this.node);
|
|
150
156
|
const rids = [...attrs.rids];
|
|
151
157
|
items = items.filter((i) => !rids.includes(i.id));
|
|
@@ -22,7 +22,9 @@ export class FootnotesElementView extends BlockView {
|
|
|
22
22
|
this.elementType = 'div';
|
|
23
23
|
this.checkEditability = () => {
|
|
24
24
|
var _a, _b;
|
|
25
|
-
const editable = this.node.childCount
|
|
25
|
+
const editable = this.props.getCapabilities().editArticle && this.node.childCount
|
|
26
|
+
? 'true'
|
|
27
|
+
: 'false';
|
|
26
28
|
(_a = this.contentDOM) === null || _a === void 0 ? void 0 : _a.setAttribute('contenteditable', editable);
|
|
27
29
|
(_b = this.dom) === null || _b === void 0 ? void 0 : _b.setAttribute('contenteditable', editable);
|
|
28
30
|
};
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
*/
|
|
16
16
|
import { TableFootnotesSelector, } from '@manuscripts/style-guide';
|
|
17
17
|
import { schema, } from '@manuscripts/transform';
|
|
18
|
+
import { TextSelection } from 'prosemirror-state';
|
|
18
19
|
import { findChildrenByType, findParentNodeClosestToPos, } from 'prosemirror-utils';
|
|
19
20
|
import { insertTableFootnote } from '../commands';
|
|
20
21
|
import { getChangeClasses, isDeleted, isRejectedInsert, } from '../lib/track-changes-utils';
|
|
@@ -27,6 +28,7 @@ export class InlineFootnoteView extends BaseNodeView {
|
|
|
27
28
|
super(...arguments);
|
|
28
29
|
this.findParentTableElement = () => findParentNodeClosestToPos(this.view.state.doc.resolve(this.getPos()), (node) => node.type === schema.nodes.table_element);
|
|
29
30
|
this.handleClick = () => {
|
|
31
|
+
var _a;
|
|
30
32
|
if (isDeleted(this.node)) {
|
|
31
33
|
return;
|
|
32
34
|
}
|
|
@@ -43,11 +45,24 @@ export class InlineFootnoteView extends BaseNodeView {
|
|
|
43
45
|
this.props.popper.show(this.dom, this.popperContainer, 'bottom-end');
|
|
44
46
|
}
|
|
45
47
|
else {
|
|
46
|
-
|
|
48
|
+
if ((_a = this.node.attrs.rids) === null || _a === void 0 ? void 0 : _a.length) {
|
|
49
|
+
let nodePos = undefined;
|
|
50
|
+
this.view.state.doc.descendants((node, pos) => {
|
|
51
|
+
if (node.attrs.id === this.node.attrs.rids[0]) {
|
|
52
|
+
nodePos = pos;
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
if (nodePos && this.props.dispatch) {
|
|
56
|
+
const sel = TextSelection.near(this.view.state.doc.resolve(nodePos + 1));
|
|
57
|
+
this.props.dispatch(this.view.state.tr.setSelection(sel).scrollIntoView());
|
|
58
|
+
}
|
|
59
|
+
}
|
|
47
60
|
}
|
|
48
61
|
};
|
|
49
62
|
this.updateContents = () => {
|
|
50
|
-
|
|
63
|
+
const node = this.node;
|
|
64
|
+
this.dom.setAttribute('rids', node.attrs.rids.join(','));
|
|
65
|
+
this.dom.setAttribute('contents', node.attrs.contents);
|
|
51
66
|
this.dom.className = [
|
|
52
67
|
'footnote',
|
|
53
68
|
...getChangeClasses(this.node.attrs.dataTracked),
|
|
@@ -36,4 +36,4 @@ export interface BibliographyProps {
|
|
|
36
36
|
}
|
|
37
37
|
declare const _default: (props: BibliographyProps) => Plugin<PluginState>;
|
|
38
38
|
export default _default;
|
|
39
|
-
export declare const getBibliographyPluginState: (state: EditorState) => PluginState;
|
|
39
|
+
export declare const getBibliographyPluginState: (state: EditorState) => PluginState | undefined;
|
|
@@ -13,15 +13,17 @@
|
|
|
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, FootnotesElementNode, InlineFootnoteNode, ManuscriptNode } from '@manuscripts/transform';
|
|
17
17
|
import { Plugin, PluginKey } from 'prosemirror-state';
|
|
18
18
|
import { PluginProps } from '../../configs/editor-plugins';
|
|
19
19
|
interface PluginState {
|
|
20
|
-
|
|
20
|
+
inlineFootnotes: [InlineFootnoteNode, number][];
|
|
21
21
|
labels: Map<string, string>;
|
|
22
|
+
footnotes: Map<string, [FootnoteNode, number]>;
|
|
23
|
+
footnoteElement?: [FootnotesElementNode, number];
|
|
22
24
|
}
|
|
23
25
|
export declare const footnotesKey: PluginKey<PluginState>;
|
|
24
|
-
export declare const buildPluginState: (doc: ManuscriptNode) => PluginState;
|
|
25
26
|
export declare const uncitedFootnoteWidget: () => () => HTMLSpanElement;
|
|
27
|
+
export declare const buildPluginState: (doc: ManuscriptNode) => PluginState;
|
|
26
28
|
declare const _default: (props: PluginProps) => Plugin<PluginState>;
|
|
27
29
|
export default _default;
|
|
@@ -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 { BaseNodeProps } from './base_node_view';
|
|
17
16
|
import BlockView from './block_view';
|
|
18
|
-
|
|
17
|
+
import { EditableBlockProps } from './editable_block';
|
|
18
|
+
export declare class FootnotesElementView<Props extends EditableBlockProps> extends BlockView<Props> {
|
|
19
19
|
elementType: string;
|
|
20
20
|
onUpdateContent(): void;
|
|
21
21
|
checkEditability: () => void;
|
|
22
22
|
}
|
|
23
|
-
declare const _default: (props: BaseNodeProps) => import("../types").NodeViewCreator<FootnotesElementView<any>>;
|
|
23
|
+
declare const _default: (props: import("./base_node_view").BaseNodeProps) => import("../types").NodeViewCreator<FootnotesElementView<any>>;
|
|
24
24
|
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": "1.9.
|
|
4
|
+
"version": "1.9.7-LEAN-3136",
|
|
5
5
|
"repository": "github:Atypon-OpenSource/manuscripts-body-editor",
|
|
6
6
|
"license": "Apache-2.0",
|
|
7
7
|
"main": "dist/cjs",
|
|
@@ -31,8 +31,8 @@
|
|
|
31
31
|
"@manuscripts/assets": "^0.6.4",
|
|
32
32
|
"@manuscripts/json-schema": "^2.2.7",
|
|
33
33
|
"@manuscripts/library": "^1.3.6",
|
|
34
|
-
"@manuscripts/style-guide": "1.12.
|
|
35
|
-
"@manuscripts/track-changes-plugin": "1.7.10",
|
|
34
|
+
"@manuscripts/style-guide": "1.12.4",
|
|
35
|
+
"@manuscripts/track-changes-plugin": "1.7.10-LEAN-3136-2MB-3",
|
|
36
36
|
"@manuscripts/transform": "2.3.3",
|
|
37
37
|
"astrocite-eutils": "^0.16.4",
|
|
38
38
|
"mathjax-full": "^3.2.2",
|
|
@@ -111,4 +111,4 @@
|
|
|
111
111
|
"@types/react": "^17.0.2",
|
|
112
112
|
"prosemirror-tables": "^1.3.5"
|
|
113
113
|
}
|
|
114
|
-
}
|
|
114
|
+
}
|
|
@@ -686,12 +686,12 @@ Next levels are shifted 'up' by 1
|
|
|
686
686
|
}
|
|
687
687
|
|
|
688
688
|
.selected-suggestion {
|
|
689
|
-
background: #
|
|
689
|
+
background: #bce7f6 !important;
|
|
690
690
|
}
|
|
691
691
|
|
|
692
692
|
.selected-suggestion {
|
|
693
693
|
border-width: 2px 0 2px 0 !important;
|
|
694
|
-
border-color: #
|
|
694
|
+
border-color: #20aedf !important;
|
|
695
695
|
border-radius: 3px !important;
|
|
696
696
|
border-style: solid !important;
|
|
697
697
|
}
|
|
@@ -795,14 +795,14 @@ Next levels are shifted 'up' by 1
|
|
|
795
795
|
display: flex;
|
|
796
796
|
justify-content: space-between;
|
|
797
797
|
align-items: flex-start;
|
|
798
|
-
gap: 0 .5em;
|
|
798
|
+
gap: 0 0.5em;
|
|
799
799
|
}
|
|
800
800
|
.contributors-list {
|
|
801
801
|
display: flex;
|
|
802
802
|
max-width: 100%;
|
|
803
803
|
flex: 0 1 auto;
|
|
804
804
|
flex-wrap: wrap;
|
|
805
|
-
gap: 0 .25em;
|
|
805
|
+
gap: 0 0.25em;
|
|
806
806
|
}
|
|
807
807
|
.contributors .tools-panel {
|
|
808
808
|
position: initial;
|
|
@@ -825,7 +825,7 @@ Next levels are shifted 'up' by 1
|
|
|
825
825
|
left: 0;
|
|
826
826
|
top: -8px;
|
|
827
827
|
width: auto;
|
|
828
|
-
height: auto;
|
|
828
|
+
height: auto;
|
|
829
829
|
}
|
|
830
830
|
.contributor {
|
|
831
831
|
position: relative;
|
|
@@ -864,8 +864,6 @@ Next levels are shifted 'up' by 1
|
|
|
864
864
|
vertical-align: top;
|
|
865
865
|
}
|
|
866
866
|
|
|
867
|
-
|
|
868
|
-
|
|
869
867
|
.contributor-note {
|
|
870
868
|
display: inline-block;
|
|
871
869
|
font-size: 0.75em;
|
|
@@ -893,4 +891,4 @@ Next levels are shifted 'up' by 1
|
|
|
893
891
|
|
|
894
892
|
* {
|
|
895
893
|
scroll-behavior: smooth;
|
|
896
|
-
}
|
|
894
|
+
}
|
package/styles/Editor.css
CHANGED
|
@@ -937,13 +937,14 @@
|
|
|
937
937
|
|
|
938
938
|
.ProseMirror .footnote::before {
|
|
939
939
|
content: attr(contents);
|
|
940
|
-
display: inline-block;
|
|
941
940
|
position: relative;
|
|
942
941
|
cursor: pointer;
|
|
943
942
|
vertical-align: super;
|
|
943
|
+
z-index: 1;
|
|
944
944
|
font-size: 75%;
|
|
945
945
|
color: #0d79d0;
|
|
946
946
|
}
|
|
947
|
+
|
|
947
948
|
.ProseMirror .table-footer {
|
|
948
949
|
font-size: 14px;
|
|
949
950
|
padding-top: 8px;
|
|
@@ -951,7 +952,7 @@
|
|
|
951
952
|
|
|
952
953
|
.ProseMirror .table-footnotes-element:has(> div):not(:first-child)::before {
|
|
953
954
|
content: '';
|
|
954
|
-
border-bottom: 1px dashed #
|
|
955
|
+
border-bottom: 1px dashed #c9c9c9;
|
|
955
956
|
display: block;
|
|
956
957
|
margin-bottom: 8px;
|
|
957
958
|
}
|
|
@@ -975,7 +976,10 @@
|
|
|
975
976
|
position: relative;
|
|
976
977
|
}
|
|
977
978
|
|
|
978
|
-
.ProseMirror
|
|
979
|
+
.ProseMirror
|
|
980
|
+
.table-footnotes-element
|
|
981
|
+
> div:not(:has(.unctied-table-footnote))
|
|
982
|
+
p::before {
|
|
979
983
|
counter-increment: table_footnote;
|
|
980
984
|
content: counter(table_footnote);
|
|
981
985
|
display: inline-block;
|