@manuscripts/body-editor 3.14.0 → 3.15.1

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 (50) hide show
  1. package/dist/cjs/components/affiliations/AffiliationsModal.js +9 -9
  2. package/dist/cjs/components/authors/AuthorsModal.js +9 -7
  3. package/dist/cjs/components/authors-affiliations/AuthorsAndAffiliationsModals.js +1 -0
  4. package/dist/cjs/components/cross-ref-check-modal/CrossRefWarningModal.js +182 -0
  5. package/dist/cjs/components/cross-ref-check-modal/openModal.js +38 -0
  6. package/dist/cjs/components/references/ImportBibliographyForm.js +5 -2
  7. package/dist/cjs/components/references/ReferenceSearch.js +2 -2
  8. package/dist/cjs/components/references/ReferencesModal.js +2 -2
  9. package/dist/cjs/plugins/affiliations.js +6 -3
  10. package/dist/cjs/plugins/bibliography.js +6 -3
  11. package/dist/cjs/plugins/cross-references.js +165 -2
  12. package/dist/cjs/plugins/footnotes.js +6 -3
  13. package/dist/cjs/versions.js +1 -1
  14. package/dist/cjs/views/embed.js +2 -2
  15. package/dist/cjs/views/footnote.js +2 -2
  16. package/dist/es/components/affiliations/AffiliationsModal.js +1 -1
  17. package/dist/es/components/authors/AuthorsModal.js +3 -1
  18. package/dist/es/components/authors-affiliations/AuthorsAndAffiliationsModals.js +1 -0
  19. package/dist/es/components/cross-ref-check-modal/CrossRefWarningModal.js +142 -0
  20. package/dist/es/components/cross-ref-check-modal/openModal.js +31 -0
  21. package/dist/es/components/references/ImportBibliographyForm.js +1 -1
  22. package/dist/es/components/references/ReferenceSearch.js +1 -1
  23. package/dist/es/components/references/ReferencesModal.js +1 -1
  24. package/dist/es/plugins/affiliations.js +1 -1
  25. package/dist/es/plugins/bibliography.js +1 -1
  26. package/dist/es/plugins/cross-references.js +163 -3
  27. package/dist/es/plugins/footnotes.js +1 -1
  28. package/dist/es/versions.js +1 -1
  29. package/dist/es/views/embed.js +1 -1
  30. package/dist/es/views/footnote.js +1 -1
  31. package/dist/types/components/authors-affiliations/AuthorsAndAffiliationsModals.d.ts +1 -1
  32. package/dist/types/components/cross-ref-check-modal/CrossRefWarningModal.d.ts +29 -0
  33. package/dist/types/components/cross-ref-check-modal/openModal.d.ts +19 -0
  34. package/dist/types/versions.d.ts +1 -1
  35. package/package.json +2 -2
  36. package/src/components/affiliations/AffiliationsModal.tsx +1 -1
  37. package/src/components/authors/AuthorsModal.tsx +3 -1
  38. package/src/components/authors-affiliations/AuthorsAndAffiliationsModals.tsx +2 -0
  39. package/src/components/cross-ref-check-modal/CrossRefWarningModal.tsx +223 -0
  40. package/src/components/cross-ref-check-modal/openModal.ts +50 -0
  41. package/src/components/references/ImportBibliographyForm.tsx +1 -1
  42. package/src/components/references/ReferenceSearch.tsx +1 -1
  43. package/src/components/references/ReferencesModal.tsx +1 -1
  44. package/src/plugins/affiliations.ts +1 -1
  45. package/src/plugins/bibliography.ts +1 -1
  46. package/src/plugins/cross-references.ts +233 -7
  47. package/src/plugins/footnotes.ts +1 -1
  48. package/src/versions.ts +1 -1
  49. package/src/views/embed.ts +1 -1
  50. package/src/views/footnote.ts +1 -1
@@ -39,7 +39,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
39
39
  exports.AffiliationsModal = void 0;
40
40
  const style_guide_1 = require("@manuscripts/style-guide");
41
41
  const transform_1 = require("@manuscripts/transform");
42
- const lodash_1 = require("lodash");
42
+ const isEqual_1 = __importDefault(require("lodash/isEqual"));
43
43
  const react_1 = __importStar(require("react"));
44
44
  const styled_components_1 = __importDefault(require("styled-components"));
45
45
  const authors_1 = require("../../lib/authors");
@@ -126,11 +126,11 @@ const AffiliationsModal = ({ authors: $authors, affiliations: $affiliations, aff
126
126
  }, []);
127
127
  const handleClose = () => {
128
128
  const values = valuesRef.current;
129
- const hasAffiliationChanges = selection && !(0, lodash_1.isEqual)(values, (0, normalize_1.checkID)(selection, 'affiliation'));
129
+ const hasAffiliationChanges = selection && !(0, isEqual_1.default)(values, (0, normalize_1.checkID)(selection, 'affiliation'));
130
130
  const originalAuthors = selection
131
131
  ? (affiliationAuthorMap.get(selection.id) ?? [])
132
132
  : [];
133
- const hasAuthorChanges = !(0, lodash_1.isEqual)(originalAuthors.sort(), selectedAuthorIds.sort());
133
+ const hasAuthorChanges = !(0, isEqual_1.default)(originalAuthors.sort(), selectedAuthorIds.sort());
134
134
  const hasChanges = hasAffiliationChanges || (selection && hasAuthorChanges);
135
135
  const isInstitutionEmpty = values?.institution?.trim() === '';
136
136
  if (hasChanges) {
@@ -149,11 +149,11 @@ const AffiliationsModal = ({ authors: $authors, affiliations: $affiliations, aff
149
149
  };
150
150
  const handleSelect = (affiliation) => {
151
151
  const values = valuesRef.current;
152
- const hasAffiliationChanges = selection && !(0, lodash_1.isEqual)(values, (0, normalize_1.checkID)(selection, 'affiliation'));
152
+ const hasAffiliationChanges = selection && !(0, isEqual_1.default)(values, (0, normalize_1.checkID)(selection, 'affiliation'));
153
153
  const originalAuthors = selection
154
154
  ? (affiliationAuthorMap.get(selection.id) ?? [])
155
155
  : [];
156
- const hasAuthorChanges = !(0, lodash_1.isEqual)(originalAuthors.sort(), selectedAuthorIds.sort());
156
+ const hasAuthorChanges = !(0, isEqual_1.default)(originalAuthors.sort(), selectedAuthorIds.sort());
157
157
  const hasChanges = hasAffiliationChanges || hasAuthorChanges;
158
158
  const isInstitutionEmpty = values?.institution?.trim() === '';
159
159
  if (hasChanges) {
@@ -234,9 +234,9 @@ const AffiliationsModal = ({ authors: $authors, affiliations: $affiliations, aff
234
234
  }
235
235
  const isInstitutionEmpty = !values.institution?.trim();
236
236
  const hasAffiliationChanges = selection &&
237
- !(0, lodash_1.isEqual)((0, normalize_1.checkID)(values, 'affiliation'), (0, normalize_1.checkID)(selection, 'affiliation'));
237
+ !(0, isEqual_1.default)((0, normalize_1.checkID)(values, 'affiliation'), (0, normalize_1.checkID)(selection, 'affiliation'));
238
238
  const originalAuthors = affiliationAuthorMap.get(selection.id) ?? [];
239
- const hasAuthorChanges = selection && !(0, lodash_1.isEqual)(originalAuthors.sort(), selectedAuthorIds.sort());
239
+ const hasAuthorChanges = selection && !(0, isEqual_1.default)(originalAuthors.sort(), selectedAuthorIds.sort());
240
240
  const shouldEnableSave = !isInstitutionEmpty && (hasAffiliationChanges || hasAuthorChanges);
241
241
  setIsDisableSave(!shouldEnableSave);
242
242
  };
@@ -272,9 +272,9 @@ const AffiliationsModal = ({ authors: $authors, affiliations: $affiliations, aff
272
272
  ? selectedAuthorIds.filter((id) => id !== authorId)
273
273
  : [...selectedAuthorIds, authorId];
274
274
  setSelectedAuthorIds(newSelectedAuthorIds);
275
- const hasAffiliationChanges = !(0, lodash_1.isEqual)(valuesRef.current, (0, normalize_1.checkID)(selection, 'affiliation'));
275
+ const hasAffiliationChanges = !(0, isEqual_1.default)(valuesRef.current, (0, normalize_1.checkID)(selection, 'affiliation'));
276
276
  const originalAuthors = affiliationAuthorMap.get(selection.id) ?? [];
277
- const hasAuthorChanges = !(0, lodash_1.isEqual)(originalAuthors.sort(), newSelectedAuthorIds.sort());
277
+ const hasAuthorChanges = !(0, isEqual_1.default)(originalAuthors.sort(), newSelectedAuthorIds.sort());
278
278
  const isInstitutionEmpty = !valuesRef.current?.institution?.trim();
279
279
  const shouldEnableSave = !isInstitutionEmpty && (hasAffiliationChanges || hasAuthorChanges);
280
280
  setIsDisableSave(!shouldEnableSave);
@@ -54,7 +54,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
54
54
  exports.AuthorsModal = exports.authorsReducer = void 0;
55
55
  const style_guide_1 = require("@manuscripts/style-guide");
56
56
  const transform_1 = require("@manuscripts/transform");
57
- const lodash_1 = require("lodash");
57
+ const cloneDeep_1 = __importDefault(require("lodash/cloneDeep"));
58
+ const isEqual_1 = __importDefault(require("lodash/isEqual"));
59
+ const omit_1 = __importDefault(require("lodash/omit"));
58
60
  const react_1 = __importStar(require("react"));
59
61
  const styled_components_1 = __importDefault(require("styled-components"));
60
62
  const array_reducer_1 = require("../../lib/array-reducer");
@@ -139,7 +141,7 @@ const AuthorsModal = ({ authors: $authors, affiliations: $affiliations, author,
139
141
  if (values && selection) {
140
142
  const normalizedSelection = (0, normalize_1.normalizeAuthor)(selection);
141
143
  const normalizedValues = (0, normalize_1.normalizeAuthor)(values);
142
- const hasChanges = !(0, lodash_1.isEqual)(normalizedSelection, normalizedValues);
144
+ const hasChanges = !(0, isEqual_1.default)(normalizedSelection, normalizedValues);
143
145
  if (hasChanges && !isDisableSave) {
144
146
  setShowConfirmationDialog(true);
145
147
  setNextAuthor(author);
@@ -227,7 +229,7 @@ const AuthorsModal = ({ authors: $authors, affiliations: $affiliations, author,
227
229
  });
228
230
  };
229
231
  const moveAuthor = (0, react_1.useCallback)((from, to, shift) => {
230
- const copy = (0, lodash_1.cloneDeep)(authors);
232
+ const copy = (0, cloneDeep_1.default)(authors);
231
233
  const order = copy.map((a, i) => {
232
234
  if (a.id === from.id) {
233
235
  if (to.priority) {
@@ -265,7 +267,7 @@ const AuthorsModal = ({ authors: $authors, affiliations: $affiliations, author,
265
267
  setIsCreatingNewAuthor(true);
266
268
  if (values &&
267
269
  selection &&
268
- !(0, lodash_1.isEqual)((0, normalize_1.normalizeAuthor)(values), (0, normalize_1.normalizeAuthor)(selection))) {
270
+ !(0, isEqual_1.default)((0, normalize_1.normalizeAuthor)(values), (0, normalize_1.normalizeAuthor)(selection))) {
269
271
  if (isDisableSave) {
270
272
  setShowRequiredFieldConfirmationDialog(true);
271
273
  }
@@ -307,10 +309,10 @@ const AuthorsModal = ({ authors: $authors, affiliations: $affiliations, author,
307
309
  setIsCreatingNewAuthor(false);
308
310
  };
309
311
  const changeAuthor = (values) => {
310
- const normalized = (0, lodash_1.omit)((0, normalize_1.normalizeAuthor)(selection), 'priority');
311
- const updatedValues = (0, lodash_1.omit)((0, normalize_1.normalizeAuthor)(values), 'priority');
312
+ const normalized = (0, omit_1.default)((0, normalize_1.normalizeAuthor)(selection), 'priority');
313
+ const updatedValues = (0, omit_1.default)((0, normalize_1.normalizeAuthor)(values), 'priority');
312
314
  const isSameAuthor = updatedValues.id === normalized.id;
313
- const hasChanges = !(0, lodash_1.isEqual)(updatedValues, normalized);
315
+ const hasChanges = !(0, isEqual_1.default)(updatedValues, normalized);
314
316
  setUnSavedChanges(isSameAuthor && hasChanges);
315
317
  valuesRef.current = { ...updatedValues, priority: values.priority };
316
318
  const { given, family, email, isCorresponding } = values;
@@ -114,5 +114,6 @@ const openAuthorsAndAffiliationsModals = (pos, view, initialModal) => {
114
114
  const dialog = (0, ReactSubView_1.default)(props, exports.AuthorsAndAffiliationsModals, componentProps, state.doc, () => pos, view);
115
115
  view.focus();
116
116
  document.body.appendChild(dialog);
117
+ return dialog;
117
118
  };
118
119
  exports.openAuthorsAndAffiliationsModals = openAuthorsAndAffiliationsModals;
@@ -0,0 +1,182 @@
1
+ "use strict";
2
+ /*!
3
+ * © 2026 Atypon Systems LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
18
+ if (k2 === undefined) k2 = k;
19
+ var desc = Object.getOwnPropertyDescriptor(m, k);
20
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
21
+ desc = { enumerable: true, get: function() { return m[k]; } };
22
+ }
23
+ Object.defineProperty(o, k2, desc);
24
+ }) : (function(o, m, k, k2) {
25
+ if (k2 === undefined) k2 = k;
26
+ o[k2] = m[k];
27
+ }));
28
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
29
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
30
+ }) : function(o, v) {
31
+ o["default"] = v;
32
+ });
33
+ var __importStar = (this && this.__importStar) || (function () {
34
+ var ownKeys = function(o) {
35
+ ownKeys = Object.getOwnPropertyNames || function (o) {
36
+ var ar = [];
37
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
38
+ return ar;
39
+ };
40
+ return ownKeys(o);
41
+ };
42
+ return function (mod) {
43
+ if (mod && mod.__esModule) return mod;
44
+ var result = {};
45
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
46
+ __setModuleDefault(result, mod);
47
+ return result;
48
+ };
49
+ })();
50
+ var __importDefault = (this && this.__importDefault) || function (mod) {
51
+ return (mod && mod.__esModule) ? mod : { "default": mod };
52
+ };
53
+ Object.defineProperty(exports, "__esModule", { value: true });
54
+ exports.CrossRefWarningModal = void 0;
55
+ const react_1 = __importStar(require("react"));
56
+ const style_guide_1 = require("@manuscripts/style-guide");
57
+ const lodash_1 = require("lodash");
58
+ const styled_components_1 = __importDefault(require("styled-components"));
59
+ const CrossRefWarningModal = ({ onClose, xrefs, onConfirm, selectAndScrollTo }) => {
60
+ const [isOpen, setIsOpen] = (0, react_1.useState)(true);
61
+ const handleClose = () => {
62
+ setIsOpen(false);
63
+ onClose();
64
+ };
65
+ return (react_1.default.createElement(Modal, { isOpen: isOpen, onRequestClose: () => handleClose(), shouldCloseOnOverlayClick: false, hideOverlay: true },
66
+ react_1.default.createElement(Container, { "data-cy": "cross-reference-warning-modal" },
67
+ react_1.default.createElement(style_guide_1.ModalHeader, null,
68
+ react_1.default.createElement(style_guide_1.CloseButton, { onClick: () => handleClose(), "data-cy": "modal-close-button" })),
69
+ react_1.default.createElement(Body, null,
70
+ react_1.default.createElement(Title, null,
71
+ react_1.default.createElement(style_guide_1.AttentionOrangeIcon, { width: 24, height: 22 }),
72
+ " Delete referenced content?"),
73
+ react_1.default.createElement("p", null, "You are deleting content referenced elsewhere in the document:"),
74
+ react_1.default.createElement(ScrolableItems, null, xrefs.map((group, i) => (react_1.default.createElement(XrefGroupDisplay, { key: i, group: group, selectAndScrollTo: selectAndScrollTo })))),
75
+ react_1.default.createElement(Actions, null,
76
+ react_1.default.createElement(style_guide_1.TertiaryButton, { type: "button", onClick: () => handleClose() }, "Cancel"),
77
+ react_1.default.createElement(style_guide_1.PrimaryButton, { "$danger": true, type: "button", onClick: () => {
78
+ onConfirm();
79
+ setIsOpen(false);
80
+ } }, "Delete & remove citation"))))));
81
+ };
82
+ exports.CrossRefWarningModal = CrossRefWarningModal;
83
+ const XrefGroupDisplay = ({ group, selectAndScrollTo }) => {
84
+ return (react_1.default.createElement("div", null,
85
+ react_1.default.createElement("h3", null, group.label),
86
+ react_1.default.createElement(ReferencesList, null, group.xrefs.map(([, pos], i) => {
87
+ return (react_1.default.createElement("li", { key: i },
88
+ react_1.default.createElement(style_guide_1.TextButton, { onClick: () => selectAndScrollTo(pos) }, `${(0, lodash_1.startCase)(pos.parent.type.name)} - ${pos.parent.textContent}`)));
89
+ }))));
90
+ };
91
+ const Container = (0, styled_components_1.default)(style_guide_1.ModalContainer) `
92
+ position: absolute;
93
+ top: 1rem;
94
+ left: 50%;
95
+ right: 0;
96
+ max-height: calc(50vh - 2rem);
97
+ min-height: 280px;
98
+ transform: translate(-50%, 0);
99
+ max-width: 480px;
100
+ transition:
101
+ top 0.2s,
102
+ transform 0.2s;
103
+ `;
104
+ const Modal = (0, styled_components_1.default)(style_guide_1.StyledModal) `
105
+ position: fixed;
106
+ top: 0;
107
+ left: 0;
108
+ width: 100%;
109
+ height: 100%;
110
+ z-index: 1100;
111
+ color: #6e6e6e;
112
+ margin: auto;
113
+
114
+ &.modal-bottom ${Container} {
115
+ top: calc(100% - 2rem);
116
+ transform: translate(-50%, -100%);
117
+ }
118
+
119
+ &:after {
120
+ content: '';
121
+ display: block;
122
+ position: fixed;
123
+ z-index: -1;
124
+ left: 0;
125
+ top: 0;
126
+ right: 0;
127
+ bottom: 0;
128
+ background: rgba(0, 0, 0, 0.2);
129
+ }
130
+ h3 {
131
+ font-size: 16px;
132
+ margin: 0.5em 0;
133
+ }
134
+ p {
135
+ margin: 0.5em 0;
136
+ }
137
+ `;
138
+ const Body = styled_components_1.default.div `
139
+ margin: 1.5rem;
140
+ display: flex;
141
+ flex-flow: column;
142
+ `;
143
+ const Title = styled_components_1.default.h2 `
144
+ font-size: 18px;
145
+ font-weight: 700;
146
+ line-height: 1.5;
147
+ margin: 0;
148
+ color: #353535;
149
+ svg {
150
+ vertical-align: text-top;
151
+ }
152
+ `;
153
+ const ReferencesList = styled_components_1.default.ul `
154
+ padding: 8px;
155
+ margin-left: 0;
156
+ list-style: none;
157
+ background: #f2f2f2;
158
+ border: 1px solid #e2e2e2;
159
+ border-radius: 3px;
160
+
161
+ ${style_guide_1.TextButton} {
162
+ margin-left: 0;
163
+ text-decoration: underline;
164
+ &:hover {
165
+ text-decoration: none;
166
+ }
167
+ display: block;
168
+ max-width: 100%;
169
+ overflow: hidden;
170
+ color: #353535;
171
+ text-overflow: ellipsis;
172
+ }
173
+ `;
174
+ const Actions = styled_components_1.default.footer `
175
+ text-align: right;
176
+ padding-top: 1rem;
177
+ `;
178
+ const ScrolableItems = styled_components_1.default.div `
179
+ max-height: 16vh;
180
+ min-height: 100px;
181
+ overflow-y: auto;
182
+ `;
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ /*!
3
+ * © 2026 Atypon Systems LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ var __importDefault = (this && this.__importDefault) || function (mod) {
18
+ return (mod && mod.__esModule) ? mod : { "default": mod };
19
+ };
20
+ Object.defineProperty(exports, "__esModule", { value: true });
21
+ exports.openCrossRefWarningModal = void 0;
22
+ const editor_props_1 = require("../../plugins/editor-props");
23
+ const ReactSubView_1 = __importDefault(require("../../views/ReactSubView"));
24
+ const CrossRefWarningModal_1 = require("./CrossRefWarningModal");
25
+ const openCrossRefWarningModal = (view, xrefGroups, onConfirm, onClose, selectAndScrollTo) => {
26
+ const { state } = view;
27
+ const props = (0, editor_props_1.getEditorProps)(state);
28
+ const componentProps = {
29
+ xrefs: xrefGroups,
30
+ onConfirm,
31
+ onClose,
32
+ selectAndScrollTo,
33
+ };
34
+ const dialog = (0, ReactSubView_1.default)(props, CrossRefWarningModal_1.CrossRefWarningModal, componentProps, state.doc, () => 0, view);
35
+ document.body.appendChild(dialog);
36
+ return dialog;
37
+ };
38
+ exports.openCrossRefWarningModal = openCrossRefWarningModal;
@@ -47,11 +47,14 @@ var __importStar = (this && this.__importStar) || (function () {
47
47
  return result;
48
48
  };
49
49
  })();
50
+ var __importDefault = (this && this.__importDefault) || function (mod) {
51
+ return (mod && mod.__esModule) ? mod : { "default": mod };
52
+ };
50
53
  Object.defineProperty(exports, "__esModule", { value: true });
51
54
  exports.ImportBibliographyForm = void 0;
52
55
  const style_guide_1 = require("@manuscripts/style-guide");
53
56
  const formik_1 = require("formik");
54
- const lodash_1 = require("lodash");
57
+ const debounce_1 = __importDefault(require("lodash/debounce"));
55
58
  const react_1 = __importStar(require("react"));
56
59
  const styled_components_1 = __importStar(require("styled-components"));
57
60
  const references_1 = require("../../lib/references");
@@ -90,7 +93,7 @@ const ImportBibliographyForm = ({ onCancel, onSave, }) => {
90
93
  formik.setFieldValue('data', []);
91
94
  }
92
95
  }, []);
93
- const debouncedGenerateData = (0, react_1.useMemo)(() => (0, lodash_1.debounce)(setDataField, 300), [setDataField]);
96
+ const debouncedGenerateData = (0, react_1.useMemo)(() => (0, debounce_1.default)(setDataField, 300), [setDataField]);
94
97
  (0, react_1.useEffect)(() => {
95
98
  debouncedGenerateData(formik.values.content);
96
99
  }, [debouncedGenerateData, formik.values.content]);
@@ -53,7 +53,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
53
53
  Object.defineProperty(exports, "__esModule", { value: true });
54
54
  exports.ReferenceSearch = void 0;
55
55
  const style_guide_1 = require("@manuscripts/style-guide");
56
- const lodash_1 = require("lodash");
56
+ const debounce_1 = __importDefault(require("lodash/debounce"));
57
57
  const react_1 = __importStar(require("react"));
58
58
  const styled_components_1 = __importDefault(require("styled-components"));
59
59
  const BibliographyItemSource_1 = require("./BibliographyItemSource");
@@ -111,7 +111,7 @@ const ReferenceSearch = ({ query: initialQuery, sources, items, onAdd, onImport,
111
111
  const items = Array.from(selections.values());
112
112
  return onCite(items);
113
113
  };
114
- const debouncedSetQuery = (0, lodash_1.debounce)((e) => {
114
+ const debouncedSetQuery = (0, debounce_1.default)((e) => {
115
115
  setQuery(e.target.value.trim());
116
116
  }, 800);
117
117
  return (react_1.default.createElement(Container, { "data-cy": 'reference-finder' },
@@ -38,7 +38,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
39
  exports.ReferencesModal = void 0;
40
40
  const style_guide_1 = require("@manuscripts/style-guide");
41
- const lodash_1 = require("lodash");
41
+ const isEqual_1 = __importDefault(require("lodash/isEqual"));
42
42
  const react_1 = __importStar(require("react"));
43
43
  const styled_components_1 = __importDefault(require("styled-components"));
44
44
  const ReferenceForm_1 = require("./ReferenceForm/ReferenceForm");
@@ -214,7 +214,7 @@ const ReferencesModal = ({ isOpen, onCancel, items, item, citationCounts, onSave
214
214
  };
215
215
  const handleItemClick = (item) => {
216
216
  const values = valuesRef.current;
217
- if (values && selection && !(0, lodash_1.isEqual)(values, normalize(selection))) {
217
+ if (values && selection && !(0, isEqual_1.default)(values, normalize(selection))) {
218
218
  setConfirm(true);
219
219
  return;
220
220
  }
@@ -14,11 +14,14 @@
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.buildPluginState = exports.affiliationsKey = void 0;
19
22
  const track_changes_plugin_1 = require("@manuscripts/track-changes-plugin");
20
23
  const transform_1 = require("@manuscripts/transform");
21
- const lodash_1 = require("lodash");
24
+ const isEqual_1 = __importDefault(require("lodash/isEqual"));
22
25
  const prosemirror_state_1 = require("prosemirror-state");
23
26
  const prosemirror_view_1 = require("prosemirror-view");
24
27
  const authors_1 = require("../lib/authors");
@@ -42,8 +45,8 @@ const buildPluginState = (doc, $old) => {
42
45
  }
43
46
  });
44
47
  if ($old &&
45
- (0, lodash_1.isEqual)(contributors, $old.contributors) &&
46
- (0, lodash_1.isEqual)(affiliations, $old.affiliations)) {
48
+ (0, isEqual_1.default)(contributors, $old.contributors) &&
49
+ (0, isEqual_1.default)(affiliations, $old.affiliations)) {
47
50
  return $old;
48
51
  }
49
52
  const iAffiliations = new Set();
@@ -47,11 +47,14 @@ var __importStar = (this && this.__importStar) || (function () {
47
47
  return result;
48
48
  };
49
49
  })();
50
+ var __importDefault = (this && this.__importDefault) || function (mod) {
51
+ return (mod && mod.__esModule) ? mod : { "default": mod };
52
+ };
50
53
  Object.defineProperty(exports, "__esModule", { value: true });
51
54
  exports.getBibliographyPluginState = exports.buildDecorations = exports.bibliographyKey = void 0;
52
55
  const transform_1 = require("@manuscripts/transform");
53
56
  const Citeproc = __importStar(require("citeproc"));
54
- const lodash_1 = require("lodash");
57
+ const isEqual_1 = __importDefault(require("lodash/isEqual"));
55
58
  const prosemirror_state_1 = require("prosemirror-state");
56
59
  const prosemirror_view_1 = require("prosemirror-view");
57
60
  exports.bibliographyKey = new prosemirror_state_1.PluginKey('bibliography');
@@ -100,8 +103,8 @@ const buildBibliographyPluginState = (doc, csl, $old) => {
100
103
  return $new;
101
104
  }
102
105
  if ($old &&
103
- (0, lodash_1.isEqual)(citations, $old.citations) &&
104
- (0, lodash_1.isEqual)(bibliographyItems, $old.bibliographyItems)) {
106
+ (0, isEqual_1.default)(citations, $old.citations) &&
107
+ (0, isEqual_1.default)(bibliographyItems, $old.bibliographyItems)) {
105
108
  $new.version = $old.version;
106
109
  $new.citationCounts = $old.citationCounts;
107
110
  $new.engine = $old.engine;
@@ -14,14 +14,66 @@
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
  const transform_1 = require("@manuscripts/transform");
19
- const lodash_1 = require("lodash");
22
+ const track_changes_plugin_1 = require("@manuscripts/track-changes-plugin");
23
+ const isEqual_1 = __importDefault(require("lodash/isEqual"));
20
24
  const prosemirror_state_1 = require("prosemirror-state");
21
25
  const prosemirror_view_1 = require("prosemirror-view");
26
+ const openModal_1 = require("../components/cross-ref-check-modal/openModal");
22
27
  const objects_1 = require("./objects");
28
+ let modalActive = false;
29
+ let modalElement = null;
23
30
  exports.default = () => {
31
+ let view = null;
24
32
  return new prosemirror_state_1.Plugin({
33
+ view(editorView) {
34
+ view = editorView;
35
+ return {
36
+ update(v) {
37
+ view = v;
38
+ },
39
+ destroy() {
40
+ view = null;
41
+ },
42
+ };
43
+ },
44
+ filterTransaction(tr, state) {
45
+ if (!view ||
46
+ !tr.docChanged ||
47
+ tr.getMeta(track_changes_plugin_1.trackChangesPluginKey) ||
48
+ tr.getMeta('addToHistory') === false) {
49
+ return true;
50
+ }
51
+ if (modalActive) {
52
+ return false;
53
+ }
54
+ const targets = objects_1.objectsKey.getState(state);
55
+ const xrefGroups = createXrefGroups(targets, state.doc, tr.doc);
56
+ if (xrefGroups.length === 0) {
57
+ return true;
58
+ }
59
+ modalActive = true;
60
+ const cleanup = () => {
61
+ modalActive = false;
62
+ if (modalElement) {
63
+ modalElement.classList.remove('modal-bottom');
64
+ modalElement.remove();
65
+ modalElement = null;
66
+ }
67
+ };
68
+ const deletedIds = new Set(xrefGroups.map((g) => g.referenced.attrs.id));
69
+ const onClose = () => {
70
+ cleanup();
71
+ };
72
+ if (view) {
73
+ modalElement = (0, openModal_1.openCrossRefWarningModal)(view, xrefGroups, onConfirmCreator(view, cleanup, deletedIds, tr), onClose, selectAndScrollToCreator(view));
74
+ }
75
+ return false;
76
+ },
25
77
  state: {
26
78
  init() {
27
79
  return prosemirror_view_1.DecorationSet.empty;
@@ -30,7 +82,7 @@ exports.default = () => {
30
82
  let decoSet = oldDecorationSet;
31
83
  const oldTargets = objects_1.objectsKey.getState(oldState);
32
84
  const newTargets = objects_1.objectsKey.getState(newState);
33
- if (tr.docChanged && !(0, lodash_1.isEqual)(oldTargets, newTargets)) {
85
+ if (tr.docChanged && !(0, isEqual_1.default)(oldTargets, newTargets)) {
34
86
  const decorations = createDecorations(tr.doc);
35
87
  decoSet = prosemirror_view_1.DecorationSet.create(tr.doc, decorations);
36
88
  }
@@ -55,3 +107,114 @@ function createDecorations(doc) {
55
107
  });
56
108
  return decorations;
57
109
  }
110
+ function createXrefGroups(targets, stateDoc, resultDoc) {
111
+ const newIds = new Set();
112
+ const xrefRids = new Set();
113
+ const xrefGroups = [];
114
+ resultDoc.descendants((node) => {
115
+ if (node.attrs.id) {
116
+ newIds.add(node.attrs.id);
117
+ }
118
+ if (node.type === transform_1.schema.nodes.cross_reference) {
119
+ for (const rid of node.attrs.rids) {
120
+ xrefRids.add(rid);
121
+ }
122
+ }
123
+ });
124
+ const orphanedRids = new Set();
125
+ for (const rid of xrefRids) {
126
+ if (!newIds.has(rid)) {
127
+ orphanedRids.add(rid);
128
+ }
129
+ }
130
+ if (orphanedRids.size === 0) {
131
+ return [];
132
+ }
133
+ const referencedNodes = new Map();
134
+ const xrefsByRid = new Map();
135
+ stateDoc.descendants((node, pos) => {
136
+ const id = node.attrs.id;
137
+ if (id && orphanedRids.has(id)) {
138
+ referencedNodes.set(id, node);
139
+ }
140
+ if (node.type === transform_1.schema.nodes.cross_reference) {
141
+ for (const rid of node.attrs.rids) {
142
+ if (orphanedRids.has(rid)) {
143
+ let entries = xrefsByRid.get(rid);
144
+ if (!entries) {
145
+ entries = [];
146
+ xrefsByRid.set(rid, entries);
147
+ }
148
+ entries.push([node, stateDoc.resolve(pos)]);
149
+ }
150
+ }
151
+ }
152
+ });
153
+ for (const [id, referenced] of referencedNodes) {
154
+ const xrefs = xrefsByRid.get(id);
155
+ if (xrefs?.length) {
156
+ const label = targets.get(referenced.attrs.id)?.label || '';
157
+ xrefGroups.push({ referenced, label, xrefs });
158
+ }
159
+ }
160
+ return xrefGroups;
161
+ }
162
+ const onConfirmCreator = (view, cleanup, deletedIds, tr) => () => {
163
+ cleanup();
164
+ if (!view) {
165
+ return;
166
+ }
167
+ const newTr = view.state.tr;
168
+ for (const step of tr.steps) {
169
+ const result = step.apply(newTr.doc);
170
+ if (result.failed) {
171
+ console.warn('Cross-ref deletion warning: could not replay step —', result.failed);
172
+ return;
173
+ }
174
+ newTr.step(step);
175
+ }
176
+ const xrefPositions = [];
177
+ newTr.doc.descendants((node, pos) => {
178
+ if (node.type === transform_1.schema.nodes.cross_reference) {
179
+ const rids = node.attrs.rids;
180
+ if (rids.some((rid) => deletedIds.has(rid))) {
181
+ xrefPositions.push({ from: pos, to: pos + node.nodeSize });
182
+ }
183
+ }
184
+ });
185
+ for (let i = xrefPositions.length - 1; i >= 0; i--) {
186
+ const { from, to } = xrefPositions[i];
187
+ newTr.delete(from, to);
188
+ }
189
+ view.dispatch(newTr);
190
+ };
191
+ const selectAndScrollToCreator = (view) => ($pos) => {
192
+ if (!view) {
193
+ return;
194
+ }
195
+ const selTr = view.state.tr;
196
+ selTr.setSelection(prosemirror_state_1.NodeSelection.create(view.state.doc, $pos.pos));
197
+ view.focus();
198
+ view.dispatch(selTr);
199
+ let scrollable = view.dom.parentElement;
200
+ while (scrollable != null &&
201
+ scrollable.scrollHeight <= scrollable.clientHeight) {
202
+ scrollable = scrollable.parentElement;
203
+ }
204
+ if (!scrollable) {
205
+ return;
206
+ }
207
+ const coords = view.coordsAtPos($pos.pos);
208
+ const containerRect = scrollable.getBoundingClientRect();
209
+ const offsetInContainer = coords.top - containerRect.top + scrollable.scrollTop;
210
+ const containerHeight = scrollable.clientHeight;
211
+ const scrollTo = offsetInContainer - containerHeight * 0.75;
212
+ if (scrollTo < 0) {
213
+ modalElement?.classList.add('modal-bottom');
214
+ scrollable.scrollTo({ top: 0, behavior: 'smooth' });
215
+ }
216
+ else {
217
+ modalElement?.classList.remove('modal-bottom');
218
+ scrollable.scrollTo({ top: scrollTo, behavior: 'smooth' });
219
+ }
220
+ };