@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.
Files changed (41) hide show
  1. package/dist/cjs/commands.js +26 -8
  2. package/dist/cjs/configs/ManuscriptsEditor.js +20 -14
  3. package/dist/cjs/configs/editor-views.js +1 -1
  4. package/dist/cjs/lib/context-menu.js +5 -2
  5. package/dist/cjs/plugins/affiliations.js +3 -0
  6. package/dist/cjs/plugins/bibliography/index.js +1 -1
  7. package/dist/cjs/plugins/footnotes/footnotes-utils.js +33 -1
  8. package/dist/cjs/plugins/footnotes/index.js +77 -25
  9. package/dist/cjs/plugins/highlight/index.js +6 -5
  10. package/dist/cjs/plugins/selected-suggestion-ui.js +8 -4
  11. package/dist/cjs/plugins/table-footnote.js +3 -0
  12. package/dist/cjs/views/base_node_view.js +1 -1
  13. package/dist/cjs/views/bibliography_element.js +6 -0
  14. package/dist/cjs/views/citation.js +3 -0
  15. package/dist/cjs/views/citation_editable.js +6 -0
  16. package/dist/cjs/views/footnotes_element.js +3 -1
  17. package/dist/cjs/views/inline_footnote.js +17 -2
  18. package/dist/es/commands.js +27 -9
  19. package/dist/es/configs/ManuscriptsEditor.js +20 -14
  20. package/dist/es/configs/editor-views.js +1 -1
  21. package/dist/es/lib/context-menu.js +5 -2
  22. package/dist/es/plugins/affiliations.js +3 -0
  23. package/dist/es/plugins/bibliography/index.js +1 -1
  24. package/dist/es/plugins/footnotes/footnotes-utils.js +31 -0
  25. package/dist/es/plugins/footnotes/index.js +78 -26
  26. package/dist/es/plugins/highlight/index.js +6 -5
  27. package/dist/es/plugins/selected-suggestion-ui.js +8 -4
  28. package/dist/es/plugins/table-footnote.js +3 -0
  29. package/dist/es/views/base_node_view.js +1 -1
  30. package/dist/es/views/bibliography_element.js +6 -0
  31. package/dist/es/views/citation.js +3 -0
  32. package/dist/es/views/citation_editable.js +6 -0
  33. package/dist/es/views/footnotes_element.js +3 -1
  34. package/dist/es/views/inline_footnote.js +17 -2
  35. package/dist/types/plugins/bibliography/index.d.ts +1 -1
  36. package/dist/types/plugins/footnotes/footnotes-utils.d.ts +1 -0
  37. package/dist/types/plugins/footnotes/index.d.ts +5 -3
  38. package/dist/types/views/footnotes_element.d.ts +3 -3
  39. package/package.json +4 -4
  40. package/styles/AdvancedEditor.css +6 -8
  41. 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) => new EditorView(root, {
29
- state,
30
- editable: () => props.getCapabilities().editArticle,
31
- scrollMargin: {
32
- top: 100,
33
- bottom: 100,
34
- left: 0,
35
- right: 0,
36
- },
37
- dispatchTransaction: dispatch,
38
- nodeViews: views(props, dispatch),
39
- attributes: props.attributes,
40
- transformPasted,
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
- if (targetDom.node instanceof Element && this.props) {
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(targetDom.node, popperContainer, 'bottom-end');
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 { isFootnoteNode, isInlineFootnoteNode, schema, } from '@manuscripts/transform';
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('click', () => {
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 { nodes: oldInlineFootnoteNodes } = footnotesKey.getState(oldState);
144
- const { nodes: inlineFootnoteNodes, labels } = footnotesKey.getState(newState);
145
- if (isEqual(inlineFootnoteNodes, oldInlineFootnoteNodes)) {
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) => labels.get(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('Add new note here')));
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
- if (SET_COMMENT in meta) {
63
- props.setComment(meta[SET_COMMENT]);
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
- view.dispatch(view.state.tr.setMeta(CLEAR_SUGGESTION_ID, true));
106
- props.setEditorSelectedSuggestion(undefined);
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
- props.setEditorSelectedSuggestion(change.id);
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 ? 'true' : 'false';
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
- this.props.history.push(Object.assign(Object.assign({}, this.props.history.location), { hash: '#' + this.node.attrs.rid }));
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
- this.setDomAttrs(this.node, this.dom);
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;
@@ -27,4 +27,5 @@ interface InlineFootnote {
27
27
  pos: number;
28
28
  }
29
29
  export declare const getInlineFootnotes: (id: string, targetNode: ManuscriptNode) => InlineFootnote[];
30
+ export declare function getAlphaOrderIndices(index: number): string;
30
31
  export {};
@@ -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
- nodes: [InlineFootnoteNode, number][];
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
- export declare class FootnotesElementView<PropsType extends BaseNodeProps> extends BlockView<PropsType> {
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.5",
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.3",
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: #BCE7F6 !important;
689
+ background: #bce7f6 !important;
690
690
  }
691
691
 
692
692
  .selected-suggestion {
693
693
  border-width: 2px 0 2px 0 !important;
694
- border-color: #20AEDF !important;
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 #C9C9C9;
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 .table-footnotes-element > div:not(:has(.unctied-table-footnote)) p::before {
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;