@manuscripts/body-editor 1.9.5 → 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/lib/context-menu.js +5 -2
- 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 -25
- 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/lib/context-menu.js +5 -2
- 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 -26
- 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
|
@@ -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),
|
|
@@ -207,7 +207,10 @@ export class ContextMenu {
|
|
|
207
207
|
index: tablesFootnoteLabels.get(node.attrs.id),
|
|
208
208
|
}));
|
|
209
209
|
const targetDom = this.view.domAtPos(this.view.state.selection.from);
|
|
210
|
-
|
|
210
|
+
const targetNode = targetDom.node.nodeType === Node.TEXT_NODE
|
|
211
|
+
? targetDom.node.parentNode
|
|
212
|
+
: targetDom.node;
|
|
213
|
+
if (targetNode instanceof Element && this.props) {
|
|
211
214
|
const popperContainer = ReactSubView(Object.assign(Object.assign({}, this.props), { dispatch: this.view.dispatch }), TableFootnotesSelector, {
|
|
212
215
|
notes: footnotes,
|
|
213
216
|
onAdd: () => {
|
|
@@ -244,7 +247,7 @@ export class ContextMenu {
|
|
|
244
247
|
(_a = this.props) === null || _a === void 0 ? void 0 : _a.popper.destroy();
|
|
245
248
|
},
|
|
246
249
|
}, this.node, this.getPos, this.view, 'table-footnote-editor');
|
|
247
|
-
(_a = this.props) === null || _a === void 0 ? void 0 : _a.popper.show(
|
|
250
|
+
(_a = this.props) === null || _a === void 0 ? void 0 : _a.popper.show(targetNode, popperContainer, 'bottom-end');
|
|
248
251
|
}
|
|
249
252
|
}
|
|
250
253
|
}));
|
|
@@ -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,28 +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
|
-
nodes.push([node, pos]);
|
|
37
|
-
node.attrs.rids.forEach((rid) => {
|
|
38
|
-
labels.set(rid, String(++index));
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
});
|
|
42
|
-
return { nodes, labels };
|
|
43
|
-
};
|
|
44
29
|
const scrollToInlineFootnote = (rid, view) => {
|
|
45
30
|
view.state.doc.descendants((node, pos) => {
|
|
46
31
|
const footnote = node;
|
|
47
|
-
if (footnote.attrs.rids.includes(rid)) {
|
|
32
|
+
if (isInlineFootnoteNode(node) && footnote.attrs.rids.includes(rid)) {
|
|
48
33
|
const selection = NodeSelection.create(view.state.doc, pos);
|
|
49
34
|
view.dispatch(view.state.tr.setSelection(selection).scrollIntoView());
|
|
50
35
|
}
|
|
@@ -54,7 +39,7 @@ const labelWidget = (label, id) => (view) => {
|
|
|
54
39
|
const element = document.createElement('span');
|
|
55
40
|
element.className = 'footnote-label';
|
|
56
41
|
element.textContent = label;
|
|
57
|
-
element.addEventListener('
|
|
42
|
+
element.addEventListener('mousedown', () => {
|
|
58
43
|
scrollToInlineFootnote(id, view);
|
|
59
44
|
});
|
|
60
45
|
return element;
|
|
@@ -128,6 +113,38 @@ const deleteFootnoteWidget = (node, props, id, tableElement) => (view, getPos) =
|
|
|
128
113
|
});
|
|
129
114
|
return deleteBtn;
|
|
130
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
|
+
};
|
|
131
148
|
export default (props) => {
|
|
132
149
|
return new Plugin({
|
|
133
150
|
key: footnotesKey,
|
|
@@ -136,25 +153,60 @@ export default (props) => {
|
|
|
136
153
|
return buildPluginState(instance.doc);
|
|
137
154
|
},
|
|
138
155
|
apply(tr, value, oldState, newState) {
|
|
156
|
+
const prevState = footnotesKey.getState(oldState);
|
|
157
|
+
if (!tr.docChanged && prevState) {
|
|
158
|
+
return prevState;
|
|
159
|
+
}
|
|
139
160
|
return buildPluginState(newState.doc);
|
|
140
161
|
},
|
|
141
162
|
},
|
|
142
163
|
appendTransaction(transactions, oldState, newState) {
|
|
143
|
-
const {
|
|
144
|
-
const {
|
|
145
|
-
|
|
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))) {
|
|
146
170
|
return null;
|
|
147
171
|
}
|
|
148
172
|
const { tr } = newState;
|
|
173
|
+
const footnotesReordered = [];
|
|
174
|
+
const footnotesRest = new Map(footnotes);
|
|
149
175
|
inlineFootnoteNodes.forEach(([node, pos]) => {
|
|
150
176
|
const footnote = node;
|
|
151
177
|
const contents = footnote.attrs.rids
|
|
152
|
-
.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
|
+
})
|
|
153
186
|
.join('');
|
|
154
187
|
if (footnote.attrs.contents !== contents) {
|
|
155
188
|
tr.setNodeMarkup(pos, undefined, Object.assign(Object.assign({}, footnote.attrs), { rids: footnote.attrs.rids, contents }));
|
|
156
189
|
}
|
|
157
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);
|
|
158
210
|
return tr;
|
|
159
211
|
},
|
|
160
212
|
props: {
|
|
@@ -197,7 +249,7 @@ export default (props) => {
|
|
|
197
249
|
}
|
|
198
250
|
}
|
|
199
251
|
if (!((_a = node.firstChild) === null || _a === void 0 ? void 0 : _a.textContent)) {
|
|
200
|
-
decorations.push(Decoration.widget(pos + 2, placeholderWidget('
|
|
252
|
+
decorations.push(Decoration.widget(pos + 2, placeholderWidget('Type new footnote here')));
|
|
201
253
|
}
|
|
202
254
|
if (tableInlineFootnoteIds &&
|
|
203
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;
|