@manuscripts/body-editor 3.13.19 → 3.15.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.
Files changed (52) hide show
  1. package/dist/cjs/commands.js +30 -2
  2. package/dist/cjs/components/authors-affiliations/AuthorsAndAffiliationsModals.js +1 -0
  3. package/dist/cjs/components/cross-ref-check-modal/CrossRefWarningModal.js +182 -0
  4. package/dist/cjs/components/cross-ref-check-modal/openModal.js +38 -0
  5. package/dist/cjs/components/views/DeleteSupplementDialog.js +75 -0
  6. package/dist/cjs/icons.js +2 -1
  7. package/dist/cjs/index.js +4 -1
  8. package/dist/cjs/lib/files.js +17 -5
  9. package/dist/cjs/lib/supplements.js +61 -0
  10. package/dist/cjs/plugins/cross-references.js +160 -0
  11. package/dist/cjs/versions.js +1 -1
  12. package/dist/cjs/views/caption_title.js +1 -0
  13. package/dist/cjs/views/supplement.js +21 -1
  14. package/dist/es/commands.js +26 -0
  15. package/dist/es/components/authors-affiliations/AuthorsAndAffiliationsModals.js +1 -0
  16. package/dist/es/components/cross-ref-check-modal/CrossRefWarningModal.js +142 -0
  17. package/dist/es/components/cross-ref-check-modal/openModal.js +31 -0
  18. package/dist/es/components/views/DeleteSupplementDialog.js +35 -0
  19. package/dist/es/icons.js +2 -1
  20. package/dist/es/index.js +2 -0
  21. package/dist/es/lib/files.js +17 -5
  22. package/dist/es/lib/supplements.js +55 -0
  23. package/dist/es/plugins/cross-references.js +162 -2
  24. package/dist/es/versions.js +1 -1
  25. package/dist/es/views/caption_title.js +1 -0
  26. package/dist/es/views/supplement.js +22 -2
  27. package/dist/types/commands.d.ts +2 -0
  28. package/dist/types/components/authors-affiliations/AuthorsAndAffiliationsModals.d.ts +1 -1
  29. package/dist/types/components/cross-ref-check-modal/CrossRefWarningModal.d.ts +29 -0
  30. package/dist/types/components/cross-ref-check-modal/openModal.d.ts +19 -0
  31. package/dist/types/components/views/DeleteSupplementDialog.d.ts +2 -0
  32. package/dist/types/icons.d.ts +1 -0
  33. package/dist/types/index.d.ts +2 -0
  34. package/dist/types/lib/files.d.ts +2 -0
  35. package/dist/types/lib/supplements.d.ts +30 -0
  36. package/dist/types/versions.d.ts +1 -1
  37. package/package.json +2 -2
  38. package/src/commands.ts +42 -0
  39. package/src/components/authors-affiliations/AuthorsAndAffiliationsModals.tsx +2 -0
  40. package/src/components/cross-ref-check-modal/CrossRefWarningModal.tsx +223 -0
  41. package/src/components/cross-ref-check-modal/openModal.ts +50 -0
  42. package/src/components/views/DeleteSupplementDialog.tsx +88 -0
  43. package/src/icons.ts +2 -0
  44. package/src/index.ts +2 -0
  45. package/src/lib/files.ts +20 -6
  46. package/src/lib/supplements.ts +97 -0
  47. package/src/plugins/cross-references.ts +232 -6
  48. package/src/versions.ts +1 -1
  49. package/src/views/caption_title.ts +2 -0
  50. package/src/views/supplement.ts +27 -2
  51. package/src/views/supplements.ts +2 -1
  52. package/styles/Editor.css +13 -0
@@ -15,8 +15,8 @@
15
15
  * limitations under the License.
16
16
  */
17
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
- exports.addNodeComment = exports.createAndFillTableElement = exports.selectAllIsolating = exports.ignoreAtomBlockNodeForward = exports.isAtEndOfTextBlock = exports.ignoreMetaNodeBackspaceCommand = exports.ignoreAtomBlockNodeBackward = exports.isTextSelection = exports.isAtStartOfTextBlock = exports.insertTransGraphicalAbstract = exports.insertTransAbstract = exports.insertTOCSection = exports.insertBibliographySection = exports.insertList = exports.insertKeywords = exports.insertAward = exports.insertAffiliation = exports.insertContributors = exports.insertGraphicalAbstract = exports.insertBackmatterSection = exports.insertAbstractSection = exports.insertSection = exports.insertHeadshotGrid = exports.insertBoxElement = exports.insertInlineFootnote = exports.insertFootnotesElement = exports.insertTableElementFooter = exports.insertInlineEquation = exports.insertCrossReference = exports.insertInlineCitation = exports.insertLink = exports.insertSectionLabel = exports.findPosBeforeFirstSubsection = exports.insertBreak = exports.deleteBlock = exports.insertBlock = exports.insertAttachment = exports.insertSupplement = exports.insertTable = exports.insertEmbed = exports.insertFigure = exports.insertGeneralTableFootnote = exports.insertInlineTableFootnote = exports.createBlock = exports.createSelection = exports.canInsert = exports.blockActive = exports.isNodeSelection = exports.markActive = exports.addToStart = void 0;
19
- exports.paste = exports.copySelection = exports.exitEditorToContainer = exports.ignoreEnterInSubtitles = exports.insertHeroImage = exports.activateSearchReplace = exports.activateSearch = exports.autoComplete = exports.addColumns = exports.addHeaderRow = exports.addRows = exports.addInlineComment = void 0;
18
+ exports.selectAllIsolating = exports.ignoreAtomBlockNodeForward = exports.isAtEndOfTextBlock = exports.ignoreMetaNodeBackspaceCommand = exports.ignoreAtomBlockNodeBackward = exports.isTextSelection = exports.isAtStartOfTextBlock = exports.insertTransGraphicalAbstract = exports.insertTransAbstract = exports.insertTOCSection = exports.insertBibliographySection = exports.insertList = exports.insertKeywords = exports.insertAward = exports.insertAffiliation = exports.insertContributors = exports.insertGraphicalAbstract = exports.insertBackmatterSection = exports.insertAbstractSection = exports.insertSection = exports.insertHeadshotGrid = exports.insertBoxElement = exports.insertInlineFootnote = exports.insertFootnotesElement = exports.insertTableElementFooter = exports.insertInlineEquation = exports.insertCrossReference = exports.insertInlineCitation = exports.insertLink = exports.insertSectionLabel = exports.findPosBeforeFirstSubsection = exports.insertBreak = exports.deleteBlock = exports.insertBlock = exports.insertAttachment = exports.updateSupplementWeblink = exports.insertSupplementWeblink = exports.insertSupplement = exports.insertTable = exports.insertEmbed = exports.insertFigure = exports.insertGeneralTableFootnote = exports.insertInlineTableFootnote = exports.createBlock = exports.createSelection = exports.canInsert = exports.blockActive = exports.isNodeSelection = exports.markActive = exports.addToStart = void 0;
19
+ exports.paste = exports.copySelection = exports.exitEditorToContainer = exports.ignoreEnterInSubtitles = exports.insertHeroImage = exports.activateSearchReplace = exports.activateSearch = exports.autoComplete = exports.addColumns = exports.addHeaderRow = exports.addRows = exports.addInlineComment = exports.addNodeComment = exports.createAndFillTableElement = void 0;
20
20
  const track_changes_plugin_1 = require("@manuscripts/track-changes-plugin");
21
21
  const transform_1 = require("@manuscripts/transform");
22
22
  const prosemirror_model_1 = require("prosemirror-model");
@@ -312,6 +312,34 @@ const insertSupplement = (file, view, setSelection = true) => {
312
312
  return true;
313
313
  };
314
314
  exports.insertSupplement = insertSupplement;
315
+ const insertSupplementWeblink = (url, title, view) => {
316
+ const supplement = transform_1.schema.nodes.supplement.createAndFill({
317
+ id: (0, transform_1.generateNodeID)(transform_1.schema.nodes.supplement),
318
+ href: url
319
+ }, createAndFillCaption());
320
+ const tr = view.state.tr;
321
+ const { pos } = (0, doc_1.upsertSupplementsSection)(tr, supplement);
322
+ tr.setSelection(prosemirror_state_1.NodeSelection.create(tr.doc, pos));
323
+ view.focus();
324
+ view.dispatch(tr.scrollIntoView());
325
+ return true;
326
+ };
327
+ exports.insertSupplementWeblink = insertSupplementWeblink;
328
+ const updateSupplementWeblink = (pos, url, title, view) => {
329
+ const node = view.state.doc.nodeAt(pos);
330
+ if (!node) {
331
+ return false;
332
+ }
333
+ const tr = view.state.tr;
334
+ tr.setNodeMarkup(pos, undefined, {
335
+ ...node.attrs,
336
+ href: url,
337
+ title: title,
338
+ });
339
+ view.dispatch(tr);
340
+ return true;
341
+ };
342
+ exports.updateSupplementWeblink = updateSupplementWeblink;
315
343
  const insertAttachment = (file, state, type, dispatch) => {
316
344
  const tr = state.tr;
317
345
  const attachments = (0, doc_1.insertAttachmentsNode)(tr);
@@ -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;
@@ -0,0 +1,75 @@
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 () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.openDeleteSupplementDialog = void 0;
40
+ const style_guide_1 = require("@manuscripts/style-guide");
41
+ const react_1 = __importStar(require("react"));
42
+ const supplements_1 = require("../../lib/supplements");
43
+ const editor_props_1 = require("../../plugins/editor-props");
44
+ const ReactSubView_1 = __importDefault(require("../../views/ReactSubView"));
45
+ const DeleteSupplementDialog = ({ label, onDelete }) => {
46
+ const [isOpen, setOpen] = (0, react_1.useState)(true);
47
+ return (react_1.default.createElement(style_guide_1.Dialog, { isOpen: isOpen, category: style_guide_1.Category.confirmation, header: 'Delete supplement', message: 'Are you sure you want to delete \u201C{label}\u201D?', actions: {
48
+ primary: {
49
+ action: () => {
50
+ onDelete();
51
+ setOpen(false);
52
+ },
53
+ title: 'Delete',
54
+ },
55
+ secondary: {
56
+ action: () => setOpen(false),
57
+ title: 'Cancel',
58
+ },
59
+ } }));
60
+ };
61
+ const openDeleteSupplementDialog = (view, pos) => {
62
+ const node = view.state.doc.nodeAt(pos);
63
+ if (!node || node.type.name !== 'supplement') {
64
+ return;
65
+ }
66
+ const { state } = view;
67
+ const props = (0, editor_props_1.getEditorProps)(state);
68
+ const label = (0, supplements_1.getSupplementDisplayLabel)(node, props.getFiles());
69
+ const dialog = (0, ReactSubView_1.default)(props, DeleteSupplementDialog, {
70
+ label,
71
+ onDelete: () => (0, supplements_1.performDeleteSupplement)(view, pos),
72
+ }, state.doc, () => 0, view);
73
+ document.body.appendChild(dialog);
74
+ };
75
+ exports.openDeleteSupplementDialog = openDeleteSupplementDialog;
package/dist/cjs/icons.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ORCIDIcon = exports.tickIcon = exports.fileMainDocumentIcon = exports.leadingHalfLeftIcon = exports.leadingWallpaperIcon = exports.leadingLargeFloatIcon = exports.leadingSmallFloatIcon = exports.leadingHeroImageIcon = exports.linkIcon = exports.translateIcon = exports.draggableIcon = exports.fileCorruptedIcon = exports.imageDefaultIcon = exports.imageLeftIcon = exports.imageRightIcon = exports.plusIcon = exports.lockIcon = exports.scrollIcon = exports.sectionCategoryIcon = exports.editIcon = exports.deleteIcon = exports.cameraIcon = exports.alertIcon = exports.arrowUp = exports.arrowDown = exports.addAuthorIcon = void 0;
3
+ exports.webLinkIcon = exports.ORCIDIcon = exports.tickIcon = exports.fileMainDocumentIcon = exports.leadingHalfLeftIcon = exports.leadingWallpaperIcon = exports.leadingLargeFloatIcon = exports.leadingSmallFloatIcon = exports.leadingHeroImageIcon = exports.linkIcon = exports.translateIcon = exports.draggableIcon = exports.fileCorruptedIcon = exports.imageDefaultIcon = exports.imageLeftIcon = exports.imageRightIcon = exports.plusIcon = exports.lockIcon = exports.scrollIcon = exports.sectionCategoryIcon = exports.editIcon = exports.deleteIcon = exports.cameraIcon = exports.alertIcon = exports.arrowUp = exports.arrowDown = exports.addAuthorIcon = void 0;
4
4
  const style_guide_1 = require("@manuscripts/style-guide");
5
5
  const react_1 = require("react");
6
6
  const server_1 = require("react-dom/server");
@@ -31,3 +31,4 @@ exports.leadingHalfLeftIcon = renderIcon(style_guide_1.LeadingHalfLeftIcon);
31
31
  exports.fileMainDocumentIcon = renderIcon(style_guide_1.FileMainDocumentIcon);
32
32
  exports.tickIcon = renderIcon(style_guide_1.TickIcon);
33
33
  exports.ORCIDIcon = renderIcon(style_guide_1.ORCIDIcon);
34
+ exports.webLinkIcon = renderIcon(style_guide_1.WebLinkIcon);
package/dist/cjs/index.js CHANGED
@@ -32,7 +32,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
32
32
  return (mod && mod.__esModule) ? mod : { "default": mod };
33
33
  };
34
34
  Object.defineProperty(exports, "__esModule", { value: true });
35
- exports.affiliationLabel = exports.authorLabel = exports.bibliographyItemTypes = exports.metadata = exports.getClosestMatch = exports.getNewMatch = exports.detectInconsistencyPluginKey = exports.searchReplacePluginKey = exports.bibliographyPluginKey = exports.footnotesPluginKey = exports.objectsPluginKey = exports.selectedSuggestionKey = exports.PopperManager = exports.CollabProvider = exports.openKeyboardShortcuts = exports.KeyboardShortcutsModal = exports.LanguageDropdown = exports.TypeSelector = exports.OutlineItemIcon = exports.ManuscriptOutline = void 0;
35
+ exports.affiliationLabel = exports.authorLabel = exports.bibliographyItemTypes = exports.metadata = exports.getClosestMatch = exports.getNewMatch = exports.detectInconsistencyPluginKey = exports.searchReplacePluginKey = exports.bibliographyPluginKey = exports.footnotesPluginKey = exports.objectsPluginKey = exports.selectedSuggestionKey = exports.allowedHref = exports.PopperManager = exports.CollabProvider = exports.openKeyboardShortcuts = exports.KeyboardShortcutsModal = exports.LanguageDropdown = exports.TypeSelector = exports.OutlineItemIcon = exports.ManuscriptOutline = void 0;
36
36
  __exportStar(require("./commands"), exports);
37
37
  var ManuscriptOutline_1 = require("./components/outline/ManuscriptOutline");
38
38
  Object.defineProperty(exports, "ManuscriptOutline", { enumerable: true, get: function () { return ManuscriptOutline_1.ManuscriptOutline; } });
@@ -57,6 +57,9 @@ __exportStar(require("./lib/capabilities"), exports);
57
57
  __exportStar(require("./lib/navigation-utils"), exports);
58
58
  __exportStar(require("./lib/comments"), exports);
59
59
  __exportStar(require("./lib/files"), exports);
60
+ __exportStar(require("./lib/supplements"), exports);
61
+ var url_1 = require("./lib/url");
62
+ Object.defineProperty(exports, "allowedHref", { enumerable: true, get: function () { return url_1.allowedHref; } });
60
63
  __exportStar(require("./lib/footnotes"), exports);
61
64
  __exportStar(require("./lib/template"), exports);
62
65
  __exportStar(require("./lib/doc"), exports);
@@ -5,6 +5,7 @@ exports.memoGroupFiles = memoGroupFiles;
5
5
  const transform_1 = require("@manuscripts/transform");
6
6
  const prosemirror_utils_1 = require("prosemirror-utils");
7
7
  const track_changes_utils_1 = require("./track-changes-utils");
8
+ const url_1 = require("./url");
8
9
  const MISSING_FILE = {
9
10
  id: '',
10
11
  name: '',
@@ -33,6 +34,7 @@ const groupFiles = (doc, files) => {
33
34
  const fileMap = new Map(files.map((f) => [f.id, f]));
34
35
  const figures = [];
35
36
  const supplements = [];
37
+ const weblinks = [];
36
38
  const linkedFiles = [];
37
39
  const attachments = [];
38
40
  const getFile = (href) => {
@@ -95,11 +97,20 @@ const groupFiles = (doc, files) => {
95
97
  }
96
98
  }
97
99
  if (node.type === transform_1.schema.nodes.supplement) {
98
- supplements.push({
99
- node,
100
- pos,
101
- file: getFile(node.attrs.href),
102
- });
100
+ const href = node.attrs.href;
101
+ if ((0, url_1.allowedHref)(href)) {
102
+ weblinks.push({
103
+ node: node,
104
+ pos,
105
+ });
106
+ }
107
+ else {
108
+ supplements.push({
109
+ node,
110
+ pos,
111
+ file: getFile(href),
112
+ });
113
+ }
103
114
  }
104
115
  if (node.type === transform_1.schema.nodes.attachment) {
105
116
  attachments.push({
@@ -112,6 +123,7 @@ const groupFiles = (doc, files) => {
112
123
  return {
113
124
  figures,
114
125
  supplements,
126
+ weblinks,
115
127
  attachments,
116
128
  linkedFiles,
117
129
  others: [...fileMap.values()],
@@ -0,0 +1,61 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.deleteSupplementAtPos = exports.performDeleteSupplement = exports.getSupplementDisplayLabel = void 0;
19
+ const transform_1 = require("@manuscripts/transform");
20
+ const prosemirror_utils_1 = require("prosemirror-utils");
21
+ const url_1 = require("./url");
22
+ const getSupplementDisplayLabel = (node, files) => {
23
+ const href = node.attrs.href;
24
+ if ((0, url_1.allowedHref)(href)) {
25
+ return href;
26
+ }
27
+ const file = files.find((f) => f.id === href);
28
+ return file?.name ?? 'Untitled supplement';
29
+ };
30
+ exports.getSupplementDisplayLabel = getSupplementDisplayLabel;
31
+ const performDeleteSupplement = (view, pos) => {
32
+ const node = view.state.doc.nodeAt(pos);
33
+ if (!node || node.type !== transform_1.schema.nodes.supplement) {
34
+ return false;
35
+ }
36
+ const from = pos;
37
+ const to = from + node.nodeSize;
38
+ const { from: deleteFrom, to: deleteTo } = (0, exports.deleteSupplementAtPos)(view.state.doc, from, to);
39
+ view.dispatch(view.state.tr.delete(deleteFrom, deleteTo));
40
+ return true;
41
+ };
42
+ exports.performDeleteSupplement = performDeleteSupplement;
43
+ const deleteSupplementAtPos = (doc, from, to) => {
44
+ const resolvedPos = doc.resolve(from);
45
+ const supplementsNodeWithPos = (0, prosemirror_utils_1.findParentNodeClosestToPos)(resolvedPos, (node) => node.type === transform_1.schema.nodes.supplements);
46
+ if (!supplementsNodeWithPos) {
47
+ return { from, to, deleteWholeSection: false };
48
+ }
49
+ const { node: supplementsNode, pos: supplementsPos } = supplementsNodeWithPos;
50
+ const supplements = (0, prosemirror_utils_1.findChildrenByType)(supplementsNode, transform_1.schema.nodes.supplement);
51
+ const isDeletingLastSupplement = supplements.length === 1;
52
+ if (isDeletingLastSupplement) {
53
+ return {
54
+ from: supplementsPos,
55
+ to: supplementsPos + supplementsNode.nodeSize,
56
+ deleteWholeSection: true,
57
+ };
58
+ }
59
+ return { from, to, deleteWholeSection: false };
60
+ };
61
+ exports.deleteSupplementAtPos = deleteSupplementAtPos;
@@ -16,12 +16,61 @@
16
16
  */
17
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
18
  const transform_1 = require("@manuscripts/transform");
19
+ const track_changes_plugin_1 = require("@manuscripts/track-changes-plugin");
19
20
  const lodash_1 = require("lodash");
20
21
  const prosemirror_state_1 = require("prosemirror-state");
21
22
  const prosemirror_view_1 = require("prosemirror-view");
23
+ const openModal_1 = require("../components/cross-ref-check-modal/openModal");
22
24
  const objects_1 = require("./objects");
25
+ let modalActive = false;
26
+ let modalElement = null;
23
27
  exports.default = () => {
28
+ let view = null;
24
29
  return new prosemirror_state_1.Plugin({
30
+ view(editorView) {
31
+ view = editorView;
32
+ return {
33
+ update(v) {
34
+ view = v;
35
+ },
36
+ destroy() {
37
+ view = null;
38
+ },
39
+ };
40
+ },
41
+ filterTransaction(tr, state) {
42
+ if (!view ||
43
+ !tr.docChanged ||
44
+ tr.getMeta(track_changes_plugin_1.trackChangesPluginKey) ||
45
+ tr.getMeta('addToHistory') === false) {
46
+ return true;
47
+ }
48
+ if (modalActive) {
49
+ return false;
50
+ }
51
+ const targets = objects_1.objectsKey.getState(state);
52
+ const xrefGroups = createXrefGroups(targets, state.doc, tr.doc);
53
+ if (xrefGroups.length === 0) {
54
+ return true;
55
+ }
56
+ modalActive = true;
57
+ const cleanup = () => {
58
+ modalActive = false;
59
+ if (modalElement) {
60
+ modalElement.classList.remove('modal-bottom');
61
+ modalElement.remove();
62
+ modalElement = null;
63
+ }
64
+ };
65
+ const deletedIds = new Set(xrefGroups.map((g) => g.referenced.attrs.id));
66
+ const onClose = () => {
67
+ cleanup();
68
+ };
69
+ if (view) {
70
+ modalElement = (0, openModal_1.openCrossRefWarningModal)(view, xrefGroups, onConfirmCreator(view, cleanup, deletedIds, tr), onClose, selectAndScrollToCreator(view));
71
+ }
72
+ return false;
73
+ },
25
74
  state: {
26
75
  init() {
27
76
  return prosemirror_view_1.DecorationSet.empty;
@@ -55,3 +104,114 @@ function createDecorations(doc) {
55
104
  });
56
105
  return decorations;
57
106
  }
107
+ function createXrefGroups(targets, stateDoc, resultDoc) {
108
+ const newIds = new Set();
109
+ const xrefRids = new Set();
110
+ const xrefGroups = [];
111
+ resultDoc.descendants((node) => {
112
+ if (node.attrs.id) {
113
+ newIds.add(node.attrs.id);
114
+ }
115
+ if (node.type === transform_1.schema.nodes.cross_reference) {
116
+ for (const rid of node.attrs.rids) {
117
+ xrefRids.add(rid);
118
+ }
119
+ }
120
+ });
121
+ const orphanedRids = new Set();
122
+ for (const rid of xrefRids) {
123
+ if (!newIds.has(rid)) {
124
+ orphanedRids.add(rid);
125
+ }
126
+ }
127
+ if (orphanedRids.size === 0) {
128
+ return [];
129
+ }
130
+ const referencedNodes = new Map();
131
+ const xrefsByRid = new Map();
132
+ stateDoc.descendants((node, pos) => {
133
+ const id = node.attrs.id;
134
+ if (id && orphanedRids.has(id)) {
135
+ referencedNodes.set(id, node);
136
+ }
137
+ if (node.type === transform_1.schema.nodes.cross_reference) {
138
+ for (const rid of node.attrs.rids) {
139
+ if (orphanedRids.has(rid)) {
140
+ let entries = xrefsByRid.get(rid);
141
+ if (!entries) {
142
+ entries = [];
143
+ xrefsByRid.set(rid, entries);
144
+ }
145
+ entries.push([node, stateDoc.resolve(pos)]);
146
+ }
147
+ }
148
+ }
149
+ });
150
+ for (const [id, referenced] of referencedNodes) {
151
+ const xrefs = xrefsByRid.get(id);
152
+ if (xrefs?.length) {
153
+ const label = targets.get(referenced.attrs.id)?.label || '';
154
+ xrefGroups.push({ referenced, label, xrefs });
155
+ }
156
+ }
157
+ return xrefGroups;
158
+ }
159
+ const onConfirmCreator = (view, cleanup, deletedIds, tr) => () => {
160
+ cleanup();
161
+ if (!view) {
162
+ return;
163
+ }
164
+ const newTr = view.state.tr;
165
+ for (const step of tr.steps) {
166
+ const result = step.apply(newTr.doc);
167
+ if (result.failed) {
168
+ console.warn('Cross-ref deletion warning: could not replay step —', result.failed);
169
+ return;
170
+ }
171
+ newTr.step(step);
172
+ }
173
+ const xrefPositions = [];
174
+ newTr.doc.descendants((node, pos) => {
175
+ if (node.type === transform_1.schema.nodes.cross_reference) {
176
+ const rids = node.attrs.rids;
177
+ if (rids.some((rid) => deletedIds.has(rid))) {
178
+ xrefPositions.push({ from: pos, to: pos + node.nodeSize });
179
+ }
180
+ }
181
+ });
182
+ for (let i = xrefPositions.length - 1; i >= 0; i--) {
183
+ const { from, to } = xrefPositions[i];
184
+ newTr.delete(from, to);
185
+ }
186
+ view.dispatch(newTr);
187
+ };
188
+ const selectAndScrollToCreator = (view) => ($pos) => {
189
+ if (!view) {
190
+ return;
191
+ }
192
+ const selTr = view.state.tr;
193
+ selTr.setSelection(prosemirror_state_1.NodeSelection.create(view.state.doc, $pos.pos));
194
+ view.focus();
195
+ view.dispatch(selTr);
196
+ let scrollable = view.dom.parentElement;
197
+ while (scrollable != null &&
198
+ scrollable.scrollHeight <= scrollable.clientHeight) {
199
+ scrollable = scrollable.parentElement;
200
+ }
201
+ if (!scrollable) {
202
+ return;
203
+ }
204
+ const coords = view.coordsAtPos($pos.pos);
205
+ const containerRect = scrollable.getBoundingClientRect();
206
+ const offsetInContainer = coords.top - containerRect.top + scrollable.scrollTop;
207
+ const containerHeight = scrollable.clientHeight;
208
+ const scrollTo = offsetInContainer - containerHeight * 0.75;
209
+ if (scrollTo < 0) {
210
+ modalElement?.classList.add('modal-bottom');
211
+ scrollable.scrollTo({ top: 0, behavior: 'smooth' });
212
+ }
213
+ else {
214
+ modalElement?.classList.remove('modal-bottom');
215
+ scrollable.scrollTo({ top: scrollTo, behavior: 'smooth' });
216
+ }
217
+ };