@manuscripts/body-editor 1.9.4 → 1.9.6

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