@manuscripts/body-editor 1.7.21 → 1.7.23-LEAN-3321-0

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.
@@ -15,7 +15,7 @@
15
15
  * limitations under the License.
16
16
  */
17
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
- exports.alertIcon = exports.editAttrsTrackingIcon = exports.commentIcon = exports.editIcon = void 0;
18
+ exports.deleteIcon = exports.alertIcon = exports.editAttrsTrackingIcon = exports.commentIcon = exports.editIcon = void 0;
19
19
  exports.editIcon = `
20
20
  <svg
21
21
  width="14"
@@ -118,3 +118,49 @@ exports.alertIcon = `
118
118
  />
119
119
  </svg>
120
120
  `;
121
+ exports.deleteIcon = `
122
+ <svg
123
+ width="13"
124
+ height="15"
125
+ viewBox="0 0 13 15"
126
+ fill="none"
127
+ xmlns="http://www.w3.org/2000/svg"
128
+ >
129
+ <path
130
+ fill-rule="evenodd"
131
+ clip-rule="evenodd"
132
+ d="M2.00001 3C2 3.00135 2 3.00269 2 3.00404V13.004C2 13.5563 2.44772 14.004 3 14.004H10C10.5523 14.004 11 13.5563 11 13.004V3.00404C11 3.00269 11 3.00135 11 3C11.5978 3.34581 12 3.99215 12 4.73244V13.004C12 14.1086 11.1046 15.004 10 15.004H3C1.89543 15.004 1 14.1086 1 13.004V4.73244C1 3.99215 1.4022 3.34581 2.00001 3Z"
133
+ fill="#C9C9C9"
134
+ />
135
+ <path
136
+ fill-rule="evenodd"
137
+ clip-rule="evenodd"
138
+ d="M4.5 0C3.67157 0 3 0.671573 3 1.5V3.5C3 4.32843 3.67157 5 4.5 5H8.5C9.32843 5 10 4.32843 10 3.5V1.5C10 0.671573 9.32843 0 8.5 0H4.5ZM9 1.5C9 1.22386 8.77614 1 8.5 1H4.5C4.22386 1 4 1.22386 4 1.5C4 1.77614 4.22386 2 4.5 2H8.5C8.77614 2 9 1.77614 9 1.5Z"
139
+ fill="#C9C9C9"
140
+ />
141
+ <rect
142
+ y="2"
143
+ width="13"
144
+ height="3"
145
+ rx="1.5"
146
+ fill="#C9C9C9"
147
+ />
148
+ <path
149
+ fill-rule="evenodd"
150
+ clip-rule="evenodd"
151
+ d="M8 7.5C8 7.22386 8.22386 7 8.5 7C8.77614 7 9 7.22386 9 7.5V11.5C9 11.7761 8.77614 12 8.5 12C8.22386 12 8 11.7761 8 11.5V7.5Z"
152
+ fill="#C9C9C9"
153
+ />
154
+ <path
155
+ fill-rule="evenodd"
156
+ clip-rule="evenodd"
157
+ d="M4 7.5C4 7.22386 4.22386 7 4.5 7C4.77614 7 5 7.22386 5 7.5V11.5C5 11.7761 4.77614 12 4.5 12C4.22386 12 4 11.7761 4 11.5V7.5Z"
158
+ fill="#C9C9C9"
159
+ />
160
+ <path
161
+ fill-rule="evenodd"
162
+ clip-rule="evenodd"
163
+ d="M11.5 3C11.7761 3 12 3.22386 12 3.5C12 3.77614 11.7761 4 11.5 4L1.5 4C1.22386 4 1 3.77614 1 3.5C1 3.22386 1.22386 3 1.5 3L11.5 3Z"
164
+ fill="white"
165
+ />
166
+ </svg>`;
@@ -128,10 +128,14 @@ const insertGeneralFootnote = (tableNode, position, view, tableElementFooter) =>
128
128
  const generalNote = state.schema.nodes.paragraph.create({
129
129
  placeholder: 'Add general note here',
130
130
  });
131
+ const tableColGroup = (0, prosemirror_utils_1.findChildrenByType)(tableNode, transform_1.schema.nodes.table_colgroup)[0];
131
132
  const tr = state.tr;
132
133
  const pos = (tableElementFooter === null || tableElementFooter === void 0 ? void 0 : tableElementFooter.length)
133
134
  ? position + tableElementFooter[0].pos + 2
134
- : position + (((_a = tableNode.content.firstChild) === null || _a === void 0 ? void 0 : _a.nodeSize) || 0);
135
+ : position +
136
+ (!tableColGroup
137
+ ? ((_a = tableNode.content.firstChild) === null || _a === void 0 ? void 0 : _a.nodeSize) || 0
138
+ : tableColGroup.pos + tableColGroup.node.nodeSize);
135
139
  if (tableElementFooter === null || tableElementFooter === void 0 ? void 0 : tableElementFooter.length) {
136
140
  tr.insert(pos, generalNote);
137
141
  }
@@ -755,14 +759,22 @@ const insertTableFootnote = (node, position, state, dispatch) => {
755
759
  tr.insert(insertionPos, footnoteElement);
756
760
  }
757
761
  else {
758
- const tableSize = (_a = node.content.firstChild) === null || _a === void 0 ? void 0 : _a.nodeSize;
759
- if (tableSize) {
760
- insertionPos = position + tableSize + 2;
761
- const tableElementFooter = transform_1.schema.nodes.table_element_footer.create({
762
- id: (0, transform_1.generateID)(json_schema_1.ObjectTypes.TableElementFooter),
763
- }, [footnoteElement]);
762
+ const tableElementFooter = transform_1.schema.nodes.table_element_footer.create({
763
+ id: (0, transform_1.generateID)(json_schema_1.ObjectTypes.TableElementFooter),
764
+ }, [footnoteElement]);
765
+ const tableColGroup = (0, prosemirror_utils_1.findChildrenByType)(node, transform_1.schema.nodes.table_colgroup)[0];
766
+ if (tableColGroup) {
767
+ insertionPos =
768
+ position + tableColGroup.pos + tableColGroup.node.nodeSize + 2;
764
769
  tr.insert(insertionPos, tableElementFooter);
765
770
  }
771
+ else {
772
+ const tableSize = (_a = node.content.firstChild) === null || _a === void 0 ? void 0 : _a.nodeSize;
773
+ if (tableSize) {
774
+ insertionPos = position + tableSize + 2;
775
+ tr.insert(insertionPos, tableElementFooter);
776
+ }
777
+ }
766
778
  }
767
779
  }
768
780
  if (dispatch && insertionPos) {
@@ -139,7 +139,7 @@ const AddKeywordInline = ({ viewProps, getUpdatedNode }) => {
139
139
  comments: [],
140
140
  }, node.type.schema.text(keyword.name));
141
141
  const nodePosition = getPos() + node.nodeSize - 1;
142
- view.dispatch(view.state.tr.insert(nodePosition - 1, keywordNode));
142
+ view.dispatch(view.state.tr.insert(nodePosition, keywordNode));
143
143
  setIsAddingNewKeyword(false);
144
144
  setNewKeyword('');
145
145
  }
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.DeleteFootnoteDialog = void 0;
27
+ const style_guide_1 = require("@manuscripts/style-guide");
28
+ const react_1 = __importStar(require("react"));
29
+ const DeleteFootnoteDialog = ({ footnoteType, footnoteMessage, handleDelete, }) => {
30
+ const [isOpen, setOpen] = (0, react_1.useState)(true);
31
+ return (react_1.default.createElement(style_guide_1.Dialog, { isOpen: isOpen, actions: {
32
+ primary: {
33
+ action: () => setOpen(false),
34
+ title: 'Cancel',
35
+ },
36
+ secondary: {
37
+ action: () => {
38
+ setOpen(false);
39
+ handleDelete();
40
+ },
41
+ title: 'Delete',
42
+ },
43
+ }, category: style_guide_1.Category.confirmation, header: `Delete ${footnoteType}`, message: `${footnoteMessage}` }));
44
+ };
45
+ exports.DeleteFootnoteDialog = DeleteFootnoteDialog;
@@ -62,7 +62,7 @@ exports.default = (props) => {
62
62
  (0, prosemirror_tables_1.tableEditing)(),
63
63
  (0, highlight_1.default)(props),
64
64
  (0, selected_suggestion_ui_1.default)(props),
65
- (0, footnotes_1.default)(),
65
+ (0, footnotes_1.default)(props),
66
66
  ];
67
67
  if (props.collabProvider) {
68
68
  allPlugins.push((0, prosemirror_collab_1.collab)({ version: props.collabProvider.currentVersion }));
@@ -14,6 +14,9 @@
14
14
  * See the License for the specific language governing permissions and
15
15
  * limitations under the License.
16
16
  */
17
+ var __importDefault = (this && this.__importDefault) || function (mod) {
18
+ return (mod && mod.__esModule) ? mod : { "default": mod };
19
+ };
17
20
  Object.defineProperty(exports, "__esModule", { value: true });
18
21
  exports.uncitedFootnoteWidget = exports.buildPluginState = exports.footnotesKey = void 0;
19
22
  const transform_1 = require("@manuscripts/transform");
@@ -22,7 +25,10 @@ const prosemirror_state_1 = require("prosemirror-state");
22
25
  const prosemirror_utils_1 = require("prosemirror-utils");
23
26
  const prosemirror_view_1 = require("prosemirror-view");
24
27
  const assets_1 = require("../../assets");
28
+ const DeleteFootnoteDialog_1 = require("../../components/views/DeleteFootnoteDialog");
29
+ const track_changes_utils_1 = require("../../lib/track-changes-utils");
25
30
  const utils_1 = require("../../lib/utils");
31
+ const ReactSubView_1 = __importDefault(require("../../views/ReactSubView"));
26
32
  const placeholder_1 = require("../placeholder");
27
33
  const footnotes_utils_1 = require("./footnotes-utils");
28
34
  exports.footnotesKey = new prosemirror_state_1.PluginKey('footnotes');
@@ -68,7 +74,60 @@ const uncitedFootnoteWidget = () => () => {
68
74
  return element;
69
75
  };
70
76
  exports.uncitedFootnoteWidget = uncitedFootnoteWidget;
71
- exports.default = () => {
77
+ const getInlineFootnote = (view, id) => {
78
+ let inlineFootnote = null;
79
+ let footnotePosition = null;
80
+ view.state.doc.descendants((node, pos) => {
81
+ var _a;
82
+ const footnote = node;
83
+ if ((_a = footnote.attrs.rids) === null || _a === void 0 ? void 0 : _a.includes(id)) {
84
+ inlineFootnote = footnote;
85
+ footnotePosition = pos;
86
+ return false;
87
+ }
88
+ });
89
+ return { node: inlineFootnote, pos: footnotePosition };
90
+ };
91
+ const deleteFootnoteWidget = (node, pos, props, footnoteType, footnoteMessage, id) => (view) => {
92
+ const deleteBtn = document.createElement('span');
93
+ deleteBtn.className = 'delete-icon';
94
+ deleteBtn.innerHTML = assets_1.deleteIcon;
95
+ deleteBtn.addEventListener('click', () => {
96
+ const handleDelete = () => {
97
+ const tr = view.state.tr;
98
+ if (node.type === transform_1.schema.nodes.table_element_footer) {
99
+ node.content.forEach((item) => {
100
+ if (item.type === transform_1.schema.nodes.paragraph) {
101
+ tr.delete(pos, pos + item.nodeSize + 1);
102
+ }
103
+ });
104
+ if (!node.childCount) {
105
+ tr.setSelection(prosemirror_state_1.TextSelection.near(view.state.doc.resolve(0))).delete(pos, pos + node.nodeSize + 1);
106
+ }
107
+ }
108
+ if (node.type === transform_1.schema.nodes.footnote) {
109
+ const inlineFootnoteResult = getInlineFootnote(view, id);
110
+ tr.setSelection(prosemirror_state_1.TextSelection.near(view.state.doc.resolve(0))).delete(pos, pos + node.nodeSize + 1);
111
+ if (inlineFootnoteResult.node) {
112
+ const pos = inlineFootnoteResult.pos;
113
+ const nodeSize = inlineFootnoteResult.node.nodeSize;
114
+ if (pos !== null && nodeSize !== null) {
115
+ tr.delete(pos, pos + nodeSize);
116
+ }
117
+ }
118
+ }
119
+ view.dispatch(tr);
120
+ };
121
+ const componentProps = {
122
+ footnoteType: footnoteType,
123
+ footnoteMessage: footnoteMessage,
124
+ handleDelete: handleDelete,
125
+ };
126
+ (0, ReactSubView_1.default)(Object.assign(Object.assign({}, props), { dispatch: view.dispatch }), DeleteFootnoteDialog_1.DeleteFootnoteDialog, componentProps, node, () => pos, view);
127
+ });
128
+ return deleteBtn;
129
+ };
130
+ exports.default = (props) => {
72
131
  return new prosemirror_state_1.Plugin({
73
132
  key: exports.footnotesKey,
74
133
  state: {
@@ -101,6 +160,7 @@ exports.default = () => {
101
160
  decorations: (state) => {
102
161
  const decorations = [];
103
162
  const isInTableElementFooter = (0, prosemirror_utils_1.hasParentNodeOfType)(transform_1.schema.nodes.table_element_footer)(state.selection);
163
+ const isInTableElement = (0, prosemirror_utils_1.hasParentNodeOfType)(transform_1.schema.nodes.table_element)(state.selection);
104
164
  if (isInTableElementFooter) {
105
165
  const parent = (0, utils_1.findParentNodeWithIdValue)(state.selection);
106
166
  if (parent) {
@@ -112,7 +172,7 @@ exports.default = () => {
112
172
  const { labels } = exports.footnotesKey.getState(state);
113
173
  let tableInlineFootnoteIds = undefined;
114
174
  state.doc.descendants((node, pos, parent) => {
115
- var _a;
175
+ var _a, _b, _c;
116
176
  if ((0, transform_1.isFootnoteNode)(node)) {
117
177
  const id = node.attrs.id;
118
178
  if (labels) {
@@ -131,6 +191,34 @@ exports.default = () => {
131
191
  decorations.push(prosemirror_view_1.Decoration.widget(pos + node.nodeSize - 1, (0, exports.uncitedFootnoteWidget)()));
132
192
  }
133
193
  }
194
+ if (isInTableElement) {
195
+ const isGeneralFootnote = ((_b = node.firstChild) === null || _b === void 0 ? void 0 : _b.type) === transform_1.schema.nodes.paragraph;
196
+ const isTableFootnote = ((_c = node.firstChild) === null || _c === void 0 ? void 0 : _c.type) === transform_1.schema.nodes.footnote;
197
+ const footnote = (() => {
198
+ switch (node.type) {
199
+ case transform_1.schema.nodes.footnote:
200
+ return {
201
+ type: 'table footnote',
202
+ message: 'This action will entirely remove the table footnote from the list because it will no longer be used.',
203
+ };
204
+ default:
205
+ return {
206
+ type: 'table general note',
207
+ message: 'This action will entirely remove the table general note.',
208
+ };
209
+ }
210
+ })();
211
+ if (isTableFootnote || isGeneralFootnote) {
212
+ decorations.push(prosemirror_view_1.Decoration.widget(pos + 2, deleteFootnoteWidget(node, pos, props, footnote.type, footnote.message, node.attrs.id), {
213
+ key: node.attrs.id,
214
+ }));
215
+ }
216
+ if ((0, track_changes_utils_1.isDeleted)(node)) {
217
+ decorations.push(prosemirror_view_1.Decoration.node(pos, pos + node.nodeSize, {
218
+ class: 'deleted-footnote',
219
+ }));
220
+ }
221
+ }
134
222
  if (node.type === transform_1.schema.nodes.footnotes_element) {
135
223
  if ((parent === null || parent === void 0 ? void 0 : parent.type) === transform_1.schema.nodes.table_element_footer) {
136
224
  decorations.push(prosemirror_view_1.Decoration.node(pos, pos + node.nodeSize, {
package/dist/es/assets.js CHANGED
@@ -115,3 +115,49 @@ export const alertIcon = `
115
115
  />
116
116
  </svg>
117
117
  `;
118
+ export const deleteIcon = `
119
+ <svg
120
+ width="13"
121
+ height="15"
122
+ viewBox="0 0 13 15"
123
+ fill="none"
124
+ xmlns="http://www.w3.org/2000/svg"
125
+ >
126
+ <path
127
+ fill-rule="evenodd"
128
+ clip-rule="evenodd"
129
+ d="M2.00001 3C2 3.00135 2 3.00269 2 3.00404V13.004C2 13.5563 2.44772 14.004 3 14.004H10C10.5523 14.004 11 13.5563 11 13.004V3.00404C11 3.00269 11 3.00135 11 3C11.5978 3.34581 12 3.99215 12 4.73244V13.004C12 14.1086 11.1046 15.004 10 15.004H3C1.89543 15.004 1 14.1086 1 13.004V4.73244C1 3.99215 1.4022 3.34581 2.00001 3Z"
130
+ fill="#C9C9C9"
131
+ />
132
+ <path
133
+ fill-rule="evenodd"
134
+ clip-rule="evenodd"
135
+ d="M4.5 0C3.67157 0 3 0.671573 3 1.5V3.5C3 4.32843 3.67157 5 4.5 5H8.5C9.32843 5 10 4.32843 10 3.5V1.5C10 0.671573 9.32843 0 8.5 0H4.5ZM9 1.5C9 1.22386 8.77614 1 8.5 1H4.5C4.22386 1 4 1.22386 4 1.5C4 1.77614 4.22386 2 4.5 2H8.5C8.77614 2 9 1.77614 9 1.5Z"
136
+ fill="#C9C9C9"
137
+ />
138
+ <rect
139
+ y="2"
140
+ width="13"
141
+ height="3"
142
+ rx="1.5"
143
+ fill="#C9C9C9"
144
+ />
145
+ <path
146
+ fill-rule="evenodd"
147
+ clip-rule="evenodd"
148
+ d="M8 7.5C8 7.22386 8.22386 7 8.5 7C8.77614 7 9 7.22386 9 7.5V11.5C9 11.7761 8.77614 12 8.5 12C8.22386 12 8 11.7761 8 11.5V7.5Z"
149
+ fill="#C9C9C9"
150
+ />
151
+ <path
152
+ fill-rule="evenodd"
153
+ clip-rule="evenodd"
154
+ d="M4 7.5C4 7.22386 4.22386 7 4.5 7C4.77614 7 5 7.22386 5 7.5V11.5C5 11.7761 4.77614 12 4.5 12C4.22386 12 4 11.7761 4 11.5V7.5Z"
155
+ fill="#C9C9C9"
156
+ />
157
+ <path
158
+ fill-rule="evenodd"
159
+ clip-rule="evenodd"
160
+ d="M11.5 3C11.7761 3 12 3.22386 12 3.5C12 3.77614 11.7761 4 11.5 4L1.5 4C1.22386 4 1 3.77614 1 3.5C1 3.22386 1.22386 3 1.5 3L11.5 3Z"
161
+ fill="white"
162
+ />
163
+ </svg>`;
@@ -119,10 +119,14 @@ export const insertGeneralFootnote = (tableNode, position, view, tableElementFoo
119
119
  const generalNote = state.schema.nodes.paragraph.create({
120
120
  placeholder: 'Add general note here',
121
121
  });
122
+ const tableColGroup = findChildrenByType(tableNode, schema.nodes.table_colgroup)[0];
122
123
  const tr = state.tr;
123
124
  const pos = (tableElementFooter === null || tableElementFooter === void 0 ? void 0 : tableElementFooter.length)
124
125
  ? position + tableElementFooter[0].pos + 2
125
- : position + (((_a = tableNode.content.firstChild) === null || _a === void 0 ? void 0 : _a.nodeSize) || 0);
126
+ : position +
127
+ (!tableColGroup
128
+ ? ((_a = tableNode.content.firstChild) === null || _a === void 0 ? void 0 : _a.nodeSize) || 0
129
+ : tableColGroup.pos + tableColGroup.node.nodeSize);
126
130
  if (tableElementFooter === null || tableElementFooter === void 0 ? void 0 : tableElementFooter.length) {
127
131
  tr.insert(pos, generalNote);
128
132
  }
@@ -718,14 +722,22 @@ export const insertTableFootnote = (node, position, state, dispatch) => {
718
722
  tr.insert(insertionPos, footnoteElement);
719
723
  }
720
724
  else {
721
- const tableSize = (_a = node.content.firstChild) === null || _a === void 0 ? void 0 : _a.nodeSize;
722
- if (tableSize) {
723
- insertionPos = position + tableSize + 2;
724
- const tableElementFooter = schema.nodes.table_element_footer.create({
725
- id: generateID(ObjectTypes.TableElementFooter),
726
- }, [footnoteElement]);
725
+ const tableElementFooter = schema.nodes.table_element_footer.create({
726
+ id: generateID(ObjectTypes.TableElementFooter),
727
+ }, [footnoteElement]);
728
+ const tableColGroup = findChildrenByType(node, schema.nodes.table_colgroup)[0];
729
+ if (tableColGroup) {
730
+ insertionPos =
731
+ position + tableColGroup.pos + tableColGroup.node.nodeSize + 2;
727
732
  tr.insert(insertionPos, tableElementFooter);
728
733
  }
734
+ else {
735
+ const tableSize = (_a = node.content.firstChild) === null || _a === void 0 ? void 0 : _a.nodeSize;
736
+ if (tableSize) {
737
+ insertionPos = position + tableSize + 2;
738
+ tr.insert(insertionPos, tableElementFooter);
739
+ }
740
+ }
729
741
  }
730
742
  }
731
743
  if (dispatch && insertionPos) {
@@ -110,7 +110,7 @@ export const AddKeywordInline = ({ viewProps, getUpdatedNode }) => {
110
110
  comments: [],
111
111
  }, node.type.schema.text(keyword.name));
112
112
  const nodePosition = getPos() + node.nodeSize - 1;
113
- view.dispatch(view.state.tr.insert(nodePosition - 1, keywordNode));
113
+ view.dispatch(view.state.tr.insert(nodePosition, keywordNode));
114
114
  setIsAddingNewKeyword(false);
115
115
  setNewKeyword('');
116
116
  }
@@ -0,0 +1,18 @@
1
+ import { Category, Dialog } from '@manuscripts/style-guide';
2
+ import React, { useState } from 'react';
3
+ export const DeleteFootnoteDialog = ({ footnoteType, footnoteMessage, handleDelete, }) => {
4
+ const [isOpen, setOpen] = useState(true);
5
+ return (React.createElement(Dialog, { isOpen: isOpen, actions: {
6
+ primary: {
7
+ action: () => setOpen(false),
8
+ title: 'Cancel',
9
+ },
10
+ secondary: {
11
+ action: () => {
12
+ setOpen(false);
13
+ handleDelete();
14
+ },
15
+ title: 'Delete',
16
+ },
17
+ }, category: Category.confirmation, header: `Delete ${footnoteType}`, message: `${footnoteMessage}` }));
18
+ };
@@ -57,7 +57,7 @@ export default (props) => {
57
57
  tableEditing(),
58
58
  highlights(props),
59
59
  selected_suggestion_ui(props),
60
- footnotes(),
60
+ footnotes(props),
61
61
  ];
62
62
  if (props.collabProvider) {
63
63
  allPlugins.push(collab({ version: props.collabProvider.currentVersion }));
@@ -15,11 +15,14 @@
15
15
  */
16
16
  import { isFootnoteNode, isInlineFootnoteNode, schema, } from '@manuscripts/transform';
17
17
  import { isEqual } from 'lodash';
18
- import { NodeSelection, Plugin, PluginKey } from 'prosemirror-state';
18
+ import { NodeSelection, Plugin, PluginKey, TextSelection, } from 'prosemirror-state';
19
19
  import { hasParentNodeOfType } from 'prosemirror-utils';
20
20
  import { Decoration, DecorationSet } from 'prosemirror-view';
21
- import { alertIcon } from '../../assets';
21
+ import { alertIcon, deleteIcon } from '../../assets';
22
+ import { DeleteFootnoteDialog, } from '../../components/views/DeleteFootnoteDialog';
23
+ import { isDeleted } from '../../lib/track-changes-utils';
22
24
  import { findParentNodeWithIdValue } from '../../lib/utils';
25
+ import ReactSubView from '../../views/ReactSubView';
23
26
  import { placeholderWidget } from '../placeholder';
24
27
  import { findTableInlineFootnoteIds } from './footnotes-utils';
25
28
  export const footnotesKey = new PluginKey('footnotes');
@@ -63,7 +66,60 @@ export const uncitedFootnoteWidget = () => () => {
63
66
  element.innerHTML = alertIcon;
64
67
  return element;
65
68
  };
66
- export default () => {
69
+ const getInlineFootnote = (view, id) => {
70
+ let inlineFootnote = null;
71
+ let footnotePosition = null;
72
+ view.state.doc.descendants((node, pos) => {
73
+ var _a;
74
+ const footnote = node;
75
+ if ((_a = footnote.attrs.rids) === null || _a === void 0 ? void 0 : _a.includes(id)) {
76
+ inlineFootnote = footnote;
77
+ footnotePosition = pos;
78
+ return false;
79
+ }
80
+ });
81
+ return { node: inlineFootnote, pos: footnotePosition };
82
+ };
83
+ const deleteFootnoteWidget = (node, pos, props, footnoteType, footnoteMessage, id) => (view) => {
84
+ const deleteBtn = document.createElement('span');
85
+ deleteBtn.className = 'delete-icon';
86
+ deleteBtn.innerHTML = deleteIcon;
87
+ deleteBtn.addEventListener('click', () => {
88
+ const handleDelete = () => {
89
+ const tr = view.state.tr;
90
+ if (node.type === schema.nodes.table_element_footer) {
91
+ node.content.forEach((item) => {
92
+ if (item.type === schema.nodes.paragraph) {
93
+ tr.delete(pos, pos + item.nodeSize + 1);
94
+ }
95
+ });
96
+ if (!node.childCount) {
97
+ tr.setSelection(TextSelection.near(view.state.doc.resolve(0))).delete(pos, pos + node.nodeSize + 1);
98
+ }
99
+ }
100
+ if (node.type === schema.nodes.footnote) {
101
+ const inlineFootnoteResult = getInlineFootnote(view, id);
102
+ tr.setSelection(TextSelection.near(view.state.doc.resolve(0))).delete(pos, pos + node.nodeSize + 1);
103
+ if (inlineFootnoteResult.node) {
104
+ const pos = inlineFootnoteResult.pos;
105
+ const nodeSize = inlineFootnoteResult.node.nodeSize;
106
+ if (pos !== null && nodeSize !== null) {
107
+ tr.delete(pos, pos + nodeSize);
108
+ }
109
+ }
110
+ }
111
+ view.dispatch(tr);
112
+ };
113
+ const componentProps = {
114
+ footnoteType: footnoteType,
115
+ footnoteMessage: footnoteMessage,
116
+ handleDelete: handleDelete,
117
+ };
118
+ ReactSubView(Object.assign(Object.assign({}, props), { dispatch: view.dispatch }), DeleteFootnoteDialog, componentProps, node, () => pos, view);
119
+ });
120
+ return deleteBtn;
121
+ };
122
+ export default (props) => {
67
123
  return new Plugin({
68
124
  key: footnotesKey,
69
125
  state: {
@@ -96,6 +152,7 @@ export default () => {
96
152
  decorations: (state) => {
97
153
  const decorations = [];
98
154
  const isInTableElementFooter = hasParentNodeOfType(schema.nodes.table_element_footer)(state.selection);
155
+ const isInTableElement = hasParentNodeOfType(schema.nodes.table_element)(state.selection);
99
156
  if (isInTableElementFooter) {
100
157
  const parent = findParentNodeWithIdValue(state.selection);
101
158
  if (parent) {
@@ -107,7 +164,7 @@ export default () => {
107
164
  const { labels } = footnotesKey.getState(state);
108
165
  let tableInlineFootnoteIds = undefined;
109
166
  state.doc.descendants((node, pos, parent) => {
110
- var _a;
167
+ var _a, _b, _c;
111
168
  if (isFootnoteNode(node)) {
112
169
  const id = node.attrs.id;
113
170
  if (labels) {
@@ -126,6 +183,34 @@ export default () => {
126
183
  decorations.push(Decoration.widget(pos + node.nodeSize - 1, uncitedFootnoteWidget()));
127
184
  }
128
185
  }
186
+ if (isInTableElement) {
187
+ const isGeneralFootnote = ((_b = node.firstChild) === null || _b === void 0 ? void 0 : _b.type) === schema.nodes.paragraph;
188
+ const isTableFootnote = ((_c = node.firstChild) === null || _c === void 0 ? void 0 : _c.type) === schema.nodes.footnote;
189
+ const footnote = (() => {
190
+ switch (node.type) {
191
+ case schema.nodes.footnote:
192
+ return {
193
+ type: 'table footnote',
194
+ message: 'This action will entirely remove the table footnote from the list because it will no longer be used.',
195
+ };
196
+ default:
197
+ return {
198
+ type: 'table general note',
199
+ message: 'This action will entirely remove the table general note.',
200
+ };
201
+ }
202
+ })();
203
+ if (isTableFootnote || isGeneralFootnote) {
204
+ decorations.push(Decoration.widget(pos + 2, deleteFootnoteWidget(node, pos, props, footnote.type, footnote.message, node.attrs.id), {
205
+ key: node.attrs.id,
206
+ }));
207
+ }
208
+ if (isDeleted(node)) {
209
+ decorations.push(Decoration.node(pos, pos + node.nodeSize, {
210
+ class: 'deleted-footnote',
211
+ }));
212
+ }
213
+ }
129
214
  if (node.type === schema.nodes.footnotes_element) {
130
215
  if ((parent === null || parent === void 0 ? void 0 : parent.type) === schema.nodes.table_element_footer) {
131
216
  decorations.push(Decoration.node(pos, pos + node.nodeSize, {
@@ -17,3 +17,4 @@ export declare const editIcon = "\n <svg\n width=\"14\"\n height=\"14\"\n
17
17
  export declare const commentIcon = "\n<svg\n width=\"20\"\n height=\"15\"\n viewBox=\"0 0 20 15\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n fill-rule=\"evenodd\"\n clip-rule=\"evenodd\"\n d=\"M7.94841 4.18311C7.98238 3.9602 8 3.73191 8 3.49951C8 3.22073 7.97465 2.94787 7.92613 2.68311H13.5C14.8854 2.68311 16.25 3.6425 16.25 5.09977V9.02453L19.1086 12.9949C19.2731 13.2233 19.2958 13.5245 19.1675 13.775C19.0392 14.0255 18.7814 14.1831 18.5 14.1831H5.5C4.11463 14.1831 2.75 13.2237 2.75 11.7664V7.93729C2.9939 7.97821 3.24446 7.99951 3.5 7.99951C3.75553 7.99951 4.00609 7.97821 4.25 7.93729V11.7664C4.25 12.1508 4.67537 12.6831 5.5 12.6831H17.0358L14.8913 9.70467C14.7994 9.57703 14.75 9.42372 14.75 9.26644V5.09977C14.75 4.71538 14.3246 4.18311 13.5 4.18311H7.94841Z\"\n fill=\"#FFBD26\"\n />\n <path\n d=\"M11.5 6.99951H8.5\"\n stroke=\"#FFBD26\"\n stroke-width=\"1.5\"\n stroke-miterlimit=\"10\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n <path\n d=\"M12 9.99951H7\"\n stroke=\"#FFBD26\"\n stroke-width=\"1.5\"\n stroke-miterlimit=\"10\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n <path\n d=\"M3.5 1L3.5 6\"\n stroke=\"#FFBD26\"\n stroke-width=\"1.5\"\n stroke-miterlimit=\"10\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n <path\n d=\"M6 3.5L1 3.5\"\n stroke=\"#FFBD26\"\n stroke-width=\"1.5\"\n stroke-miterlimit=\"10\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n";
18
18
  export declare const editAttrsTrackingIcon = "\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M12 2L14 4L9 9L6 10L7 7L12 2Z\"\n stroke=\"#353535\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n <path\n d=\"M13 10V11.5C13 12.328 12.328 13 11.5 13H4.5C3.672 13 3 12.328 3 11.5V4.5C3 3.672 3.672 3 4.5 3H6\"\n stroke=\"#353535\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n";
19
19
  export declare const alertIcon = "\n <svg\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 12 12\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n fill-rule=\"evenodd\"\n clip-rule=\"evenodd\"\n d=\"M6 12C2.68629 12 1.18852e-06 9.31371 1.47821e-06 6C1.7679e-06 2.68629 2.68629 1.39444e-07 6 4.29138e-07C9.31371 7.18831e-07 12 2.68629 12 6C12 9.31371 9.31371 12 6 12ZM6.74998 2.99996L6.75 6.37462C6.75 6.78819 6.41522 7.12243 6.00166 7.12334C5.58681 7.12426 5.25001 6.78821 5.25001 6.37335L5.25 3.00082C5.25 2.58629 5.58629 2.25037 6.00082 2.25083C6.4147 2.25128 6.74998 2.58607 6.74998 2.99996ZM6.75 8.99263C6.75 9.46884 6.47288 9.75 5.99853 9.75C5.52419 9.75 5.25 9.47179 5.25 8.99558C5.25 8.51937 5.52421 8.25 5.99855 8.25C6.47289 8.25 6.75 8.51642 6.75 8.99263Z\"\n fill=\"#FE8F1F\"\n />\n </svg>\n";
20
+ export declare const deleteIcon = "\n <svg \n width=\"13\" \n height=\"15\" \n viewBox=\"0 0 13 15\" \n fill=\"none\" \n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path \n fill-rule=\"evenodd\" \n clip-rule=\"evenodd\" \n d=\"M2.00001 3C2 3.00135 2 3.00269 2 3.00404V13.004C2 13.5563 2.44772 14.004 3 14.004H10C10.5523 14.004 11 13.5563 11 13.004V3.00404C11 3.00269 11 3.00135 11 3C11.5978 3.34581 12 3.99215 12 4.73244V13.004C12 14.1086 11.1046 15.004 10 15.004H3C1.89543 15.004 1 14.1086 1 13.004V4.73244C1 3.99215 1.4022 3.34581 2.00001 3Z\" \n fill=\"#C9C9C9\"\n />\n <path \n fill-rule=\"evenodd\" \n clip-rule=\"evenodd\" \n d=\"M4.5 0C3.67157 0 3 0.671573 3 1.5V3.5C3 4.32843 3.67157 5 4.5 5H8.5C9.32843 5 10 4.32843 10 3.5V1.5C10 0.671573 9.32843 0 8.5 0H4.5ZM9 1.5C9 1.22386 8.77614 1 8.5 1H4.5C4.22386 1 4 1.22386 4 1.5C4 1.77614 4.22386 2 4.5 2H8.5C8.77614 2 9 1.77614 9 1.5Z\" \n fill=\"#C9C9C9\"\n />\n <rect \n y=\"2\" \n width=\"13\" \n height=\"3\" \n rx=\"1.5\" \n fill=\"#C9C9C9\"\n />\n <path \n fill-rule=\"evenodd\" \n clip-rule=\"evenodd\" \n d=\"M8 7.5C8 7.22386 8.22386 7 8.5 7C8.77614 7 9 7.22386 9 7.5V11.5C9 11.7761 8.77614 12 8.5 12C8.22386 12 8 11.7761 8 11.5V7.5Z\" \n fill=\"#C9C9C9\"\n />\n <path \n fill-rule=\"evenodd\" \n clip-rule=\"evenodd\" \n d=\"M4 7.5C4 7.22386 4.22386 7 4.5 7C4.77614 7 5 7.22386 5 7.5V11.5C5 11.7761 4.77614 12 4.5 12C4.22386 12 4 11.7761 4 11.5V7.5Z\" \n fill=\"#C9C9C9\"\n />\n <path \n fill-rule=\"evenodd\" \n clip-rule=\"evenodd\" \n d=\"M11.5 3C11.7761 3 12 3.22386 12 3.5C12 3.77614 11.7761 4 11.5 4L1.5 4C1.22386 4 1 3.77614 1 3.5C1 3.22386 1.22386 3 1.5 3L11.5 3Z\" \n fill=\"white\"\n />\n</svg>";
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ export interface DeleteFootnoteDialogProps {
3
+ footnoteType: string;
4
+ footnoteMessage: string;
5
+ handleDelete: () => void;
6
+ }
7
+ export declare const DeleteFootnoteDialog: React.FC<DeleteFootnoteDialogProps>;
@@ -22,7 +22,7 @@ import { Plugin } from 'prosemirror-state';
22
22
  import { CollabProvider } from '../classes/collabProvider';
23
23
  import { PopperManager } from '../lib/popper';
24
24
  import { CSLProps } from './ManuscriptsEditor';
25
- interface PluginProps {
25
+ export interface PluginProps {
26
26
  getManuscript: () => Manuscript;
27
27
  setComment: (comment?: CommentAnnotation) => void;
28
28
  setSelectedComment: (id?: string) => void;
@@ -15,6 +15,7 @@
15
15
  */
16
16
  import { InlineFootnoteNode, ManuscriptNode } from '@manuscripts/transform';
17
17
  import { Plugin, PluginKey } from 'prosemirror-state';
18
+ import { PluginProps } from '../../configs/editor-plugins';
18
19
  interface PluginState {
19
20
  nodes: [InlineFootnoteNode, number][];
20
21
  labels: Map<string, string>;
@@ -22,5 +23,5 @@ interface PluginState {
22
23
  export declare const footnotesKey: PluginKey<PluginState>;
23
24
  export declare const buildPluginState: (doc: ManuscriptNode) => PluginState;
24
25
  export declare const uncitedFootnoteWidget: () => () => HTMLSpanElement;
25
- declare const _default: () => Plugin<PluginState>;
26
+ declare const _default: (props: PluginProps) => Plugin<PluginState>;
26
27
  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.7.21",
4
+ "version": "1.7.23-LEAN-3321-0",
5
5
  "repository": "github:Atypon-OpenSource/manuscripts-body-editor",
6
6
  "license": "Apache-2.0",
7
7
  "main": "dist/cjs",
@@ -33,7 +33,7 @@
33
33
  "@manuscripts/library": "^1.3.5",
34
34
  "@manuscripts/style-guide": "^1.8.0",
35
35
  "@manuscripts/track-changes-plugin": "^1.7.7",
36
- "@manuscripts/transform": "^2.1.6",
36
+ "@manuscripts/transform": "2.1.7-LEAN-3321",
37
37
  "astrocite-eutils": "^0.16.4",
38
38
  "axios": "^1.6.7",
39
39
  "mathjax-full": "^3.2.2",
package/styles/Editor.css CHANGED
@@ -954,8 +954,21 @@
954
954
  .ProseMirror .table-footnotes-element {
955
955
  counter-reset: table_footnote;
956
956
  }
957
-
958
- .ProseMirror .table-footnotes-element > div:not(:has(.unctied-table-footnote)) p::before {
957
+ .table-footer .delete-icon {
958
+ display: none;
959
+ position: absolute;
960
+ right: -20px;
961
+ top: -13px;
962
+ cursor: pointer;
963
+ z-index: 1;
964
+ }
965
+ .table-footer .delete-icon:hover svg path {
966
+ fill: #353535;
967
+ }
968
+ .table-footer .footnote-element .delete-icon { /* remove this after implemnting LEAN-3143*/
969
+ display: none !important;
970
+ }
971
+ .ProseMirror .table-footer .footnote-element > div:not(:has(.unctied-table-footnote)) p::before {
959
972
  counter-increment: table_footnote;
960
973
  content: counter(table_footnote);
961
974
  display: inline-block;
@@ -975,9 +988,20 @@
975
988
  background-color: #f2fbfc;
976
989
  padding: 4px;
977
990
  }
991
+
992
+ .ProseMirror .table-footer .footnote-selected .delete-icon ,.ProseMirror .table-footer .footnote-selected .deleted.rejected .delete-icon {
993
+ display: block;
994
+ }
995
+ .ProseMirror table .deleted-footnote::before , .ProseMirror .table-footer .deleted-footnote::before{
996
+ content: '' !important;
997
+ }
978
998
  .table-footer > div > p {
979
999
  padding-bottom: 10px;
980
1000
  }
1001
+ .ProseMirror .table-footer .footnote-selected {
1002
+ position: relative;
1003
+ }
1004
+
981
1005
  .ProseMirror .table-footnotes-element .footnote-selected {
982
1006
  border: 1px solid #bce7f6;
983
1007
  }
@@ -1028,4 +1052,4 @@
1028
1052
  }
1029
1053
  .highlight {
1030
1054
  background-color: #ffeebf !important;
1031
- }
1055
+ }