@manuscripts/body-editor 3.7.25 → 3.7.27

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.
@@ -63,7 +63,7 @@ const excludedTypes = [
63
63
  transform_1.schema.nodes.trans_abstract,
64
64
  transform_1.schema.nodes.subtitles,
65
65
  transform_1.schema.nodes.subtitle,
66
- transform_1.schema.nodes.supplements,
66
+ transform_1.schema.nodes.supplement,
67
67
  ];
68
68
  const childrenExcludedTypes = [
69
69
  transform_1.schema.nodes.pullquote_element,
@@ -83,6 +83,17 @@ const isAbstractOrBackmatter = (item) => {
83
83
  const isManuscriptNode = (node) => {
84
84
  return node?.type === transform_1.schema.nodes.manuscript;
85
85
  };
86
+ const isPdfFile = (file) => {
87
+ if (!file?.name) {
88
+ return false;
89
+ }
90
+ const name = file.name.toLowerCase();
91
+ return name.endsWith('.pdf');
92
+ };
93
+ const getEditorFiles = (view) => {
94
+ const props = view?.props;
95
+ return props?.getFiles?.();
96
+ };
86
97
  const buildTree = ({ node, pos, index, parent, }) => {
87
98
  const items = [];
88
99
  const startPos = pos + 1;
@@ -108,7 +119,7 @@ const buildTree = ({ node, pos, index, parent, }) => {
108
119
  return { node, index, items, pos, endPos, parent };
109
120
  };
110
121
  exports.buildTree = buildTree;
111
- const DraggableTree = ({ tree, view, depth, can, }) => {
122
+ const DraggableTree = ({ tree, view, depth, can, getFiles, }) => {
112
123
  const [dropSide, setDropSide] = (0, react_1.useState)();
113
124
  const [isOpen, setOpen] = (0, react_1.useState)(depth === 0);
114
125
  const ref = (0, react_1.useRef)(null);
@@ -202,7 +213,35 @@ const DraggableTree = ({ tree, view, depth, can, }) => {
202
213
  });
203
214
  const isDeletedItem = (0, track_changes_utils_1.isDeleted)(node);
204
215
  const isHeroImage = (0, transform_1.isHeroImageNode)(node);
205
- const isTop = isManuscriptNode(parent) && !isHeroImage;
216
+ const isSupplements = (0, transform_1.isSupplementsNode)(node);
217
+ const isMainDocument = (0, transform_1.isAttachmentsNode)(node);
218
+ const editorFiles = isMainDocument
219
+ ? (getFiles?.() ?? getEditorFiles(view))
220
+ : undefined;
221
+ const isTop = isManuscriptNode(parent) &&
222
+ !isHeroImage &&
223
+ !isSupplements &&
224
+ !isMainDocument;
225
+ if (isMainDocument && node.childCount === 0) {
226
+ return null;
227
+ }
228
+ if (isMainDocument) {
229
+ const attachmentIds = new Set();
230
+ node.forEach((childNode) => {
231
+ const href = childNode.attrs?.href;
232
+ if (href) {
233
+ attachmentIds.add(href.replace(/^attachment:/, ''));
234
+ }
235
+ });
236
+ const mainDocumentFile = editorFiles?.find((file) => {
237
+ const fileId = file.id?.replace(/^attachment:/, '');
238
+ return !!fileId && attachmentIds.has(fileId);
239
+ }) ?? editorFiles?.find((file) => isPdfFile(file));
240
+ const isMainDocumentPDF = isPdfFile(mainDocumentFile);
241
+ if (!isMainDocumentPDF) {
242
+ return null;
243
+ }
244
+ }
206
245
  const handleContextMenu = (e) => {
207
246
  e.preventDefault();
208
247
  e.stopPropagation();
@@ -231,16 +270,23 @@ const DraggableTree = ({ tree, view, depth, can, }) => {
231
270
  }
232
271
  };
233
272
  dragRef(dropRef(ref));
234
- const dragClass = isDragging ? 'dragging' : '';
235
- const dropClass = isOver && dropSide ? `drop-${dropSide}` : '';
236
- const deletedClass = isDeletedItem ? 'deleted' : '';
237
- const heroImageClass = isHeroImage ? 'hero-image' : '';
238
- return (react_1.default.createElement(Outline_1.Outline, { ref: ref, className: `${dragClass} ${dropClass} ${deletedClass} ${heroImageClass}` },
239
- !isTop && node.type.name != 'manuscript' && (react_1.default.createElement(Outline_1.OutlineItem, { depth: isHeroImage ? 1 : depth, onContextMenu: handleContextMenu, onKeyDown: handleKeyDown, tabIndex: -1, "data-outline-item": true },
273
+ const classNames = [
274
+ isDragging && 'dragging',
275
+ isOver && dropSide && `drop-${dropSide}`,
276
+ isDeletedItem && 'deleted',
277
+ isHeroImage && 'hero-image',
278
+ isSupplements && 'supplements',
279
+ (0, transform_1.isBibliographySectionNode)(node) && 'references',
280
+ isMainDocument && 'main-document',
281
+ ]
282
+ .filter(Boolean)
283
+ .join(' ');
284
+ return (react_1.default.createElement(Outline_1.Outline, { ref: ref, className: classNames },
285
+ !isTop && node.type.name != 'manuscript' && (react_1.default.createElement(Outline_1.OutlineItem, { depth: isHeroImage || isSupplements || isMainDocument ? 1 : depth, onContextMenu: handleContextMenu, onKeyDown: handleKeyDown, tabIndex: -1, "data-outline-item": true },
240
286
  items.length ? (react_1.default.createElement(Outline_1.OutlineItemArrow, { "aria-label": `${isOpen ? 'Collapse' : 'Expand'} ${node.type.name}`, onClick: toggleOpen, tabIndex: -1 }, isOpen ? react_1.default.createElement(style_guide_1.TriangleExpandedIcon, null) : react_1.default.createElement(style_guide_1.TriangleCollapsedIcon, null))) : (react_1.default.createElement(Outline_1.OutlineItemNoArrow, null)),
241
287
  react_1.default.createElement(Outline_1.OutlineItemLink, { to: `#${node.attrs.id}`, tabIndex: -1 },
242
288
  react_1.default.createElement(Outline_1.OutlineItemIcon, null, (0, node_type_icons_1.nodeTypeIcon)(node.type)),
243
289
  react_1.default.createElement(Outline_1.OutlineItemLinkText, { className: `outline-text-${node.type.name}` }, itemText(node))))),
244
- items.length ? (react_1.default.createElement("div", { className: `subtree ${isOpen ? '' : 'collapsed'}` }, items.map((subtree, index) => (react_1.default.createElement(exports.DraggableTree, { key: subtree.node.attrs.id || 'subtree-' + index, tree: subtree, view: view, depth: !tree.parent ? depth : depth + 1, can: can }))))) : null));
290
+ items.length ? (react_1.default.createElement("div", { className: `subtree ${isOpen ? '' : 'collapsed'}` }, items.map((subtree, index) => (react_1.default.createElement(exports.DraggableTree, { key: subtree.node.attrs.id || 'subtree-' + index, tree: subtree, view: view, depth: !tree.parent ? depth : depth + 1, can: can, getFiles: getFiles }))))) : null));
245
291
  };
246
292
  exports.DraggableTree = DraggableTree;
@@ -64,12 +64,12 @@ const ManuscriptOutline = (props) => {
64
64
  pos: 0,
65
65
  index: 0,
66
66
  });
67
- setValues({ tree, view, can: props.can });
67
+ setValues({ tree, view, can: props.can, getFiles: props.getFiles });
68
68
  }
69
69
  else {
70
70
  setValues(undefined);
71
71
  }
72
- }, [debouncedProps, props.can]);
72
+ }, [debouncedProps, props.can, props.getFiles]);
73
73
  const getOutlineItems = (0, react_1.useCallback)(() => {
74
74
  if (!containerRef.current)
75
75
  return [];
@@ -126,10 +126,10 @@ exports.Outline = styled_components_1.default.div `
126
126
  display: none;
127
127
  }
128
128
 
129
- & .hero-image {
130
- margin-top: 1rem;
131
- padding-top: 0.5rem;
132
- border-top: 1px dashed #ddd;
129
+ & div:has(.supplements, .hero-image, .main-document) .references {
130
+ margin-bottom: 5px;
131
+ padding-bottom: 5px;
132
+ border-bottom: 1px dashed #ddd;
133
133
  }
134
134
  `;
135
135
  exports.OutlineItemPlaceholder = styled_components_1.default.span ``;
@@ -24,6 +24,8 @@ const transform_1 = require("@manuscripts/transform");
24
24
  const react_1 = __importDefault(require("react"));
25
25
  const { nodes } = transform_1.schema;
26
26
  const OutlineImageIcon = () => (react_1.default.createElement(style_guide_1.FileImageIcon, { width: "11", height: "14" }));
27
+ const OutlineSupplementsIcon = () => (react_1.default.createElement(style_guide_1.SupplementsIcon, { width: "11", height: "14" }));
28
+ const OutlineMainDocumentIcon = () => (react_1.default.createElement(style_guide_1.FileDocumentIcon, { width: "11", height: "14" }));
27
29
  const icons = new Map([
28
30
  [nodes.manuscript, style_guide_1.OutlineManuscriptIcon],
29
31
  [nodes.bibliography_section, style_guide_1.OutlineSectionIcon],
@@ -39,6 +41,8 @@ const icons = new Map([
39
41
  [nodes.footnotes_section, style_guide_1.OutlineSectionIcon],
40
42
  [nodes.image_element, OutlineImageIcon],
41
43
  [nodes.hero_image, OutlineImageIcon],
44
+ [nodes.supplements, OutlineSupplementsIcon],
45
+ [nodes.attachments, OutlineMainDocumentIcon],
42
46
  ]);
43
47
  const nodeTypeIcon = (nodeType, listType) => {
44
48
  if (nodeType === transform_1.schema.nodes.list) {
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.MATHJAX_VERSION = exports.VERSION = void 0;
4
- exports.VERSION = '3.7.25';
4
+ exports.VERSION = '3.7.27';
5
5
  exports.MATHJAX_VERSION = '3.2.2';
@@ -1,5 +1,5 @@
1
1
  import { TriangleCollapsedIcon, TriangleExpandedIcon, } from '@manuscripts/style-guide';
2
- import { isElementNodeType, isHeroImageNode, nodeTitle, nodeTitlePlaceholder, schema, } from '@manuscripts/transform';
2
+ import { isAttachmentsNode, isBibliographySectionNode, isSupplementsNode, isElementNodeType, isHeroImageNode, nodeTitle, nodeTitlePlaceholder, schema, } from '@manuscripts/transform';
3
3
  import { Fragment } from 'prosemirror-model';
4
4
  import React, { useRef, useState } from 'react';
5
5
  import { useDrag, useDrop } from 'react-dnd';
@@ -27,7 +27,7 @@ const excludedTypes = [
27
27
  schema.nodes.trans_abstract,
28
28
  schema.nodes.subtitles,
29
29
  schema.nodes.subtitle,
30
- schema.nodes.supplements,
30
+ schema.nodes.supplement,
31
31
  ];
32
32
  const childrenExcludedTypes = [
33
33
  schema.nodes.pullquote_element,
@@ -47,6 +47,17 @@ const isAbstractOrBackmatter = (item) => {
47
47
  const isManuscriptNode = (node) => {
48
48
  return node?.type === schema.nodes.manuscript;
49
49
  };
50
+ const isPdfFile = (file) => {
51
+ if (!file?.name) {
52
+ return false;
53
+ }
54
+ const name = file.name.toLowerCase();
55
+ return name.endsWith('.pdf');
56
+ };
57
+ const getEditorFiles = (view) => {
58
+ const props = view?.props;
59
+ return props?.getFiles?.();
60
+ };
50
61
  export const buildTree = ({ node, pos, index, parent, }) => {
51
62
  const items = [];
52
63
  const startPos = pos + 1;
@@ -71,7 +82,7 @@ export const buildTree = ({ node, pos, index, parent, }) => {
71
82
  }
72
83
  return { node, index, items, pos, endPos, parent };
73
84
  };
74
- export const DraggableTree = ({ tree, view, depth, can, }) => {
85
+ export const DraggableTree = ({ tree, view, depth, can, getFiles, }) => {
75
86
  const [dropSide, setDropSide] = useState();
76
87
  const [isOpen, setOpen] = useState(depth === 0);
77
88
  const ref = useRef(null);
@@ -165,7 +176,35 @@ export const DraggableTree = ({ tree, view, depth, can, }) => {
165
176
  });
166
177
  const isDeletedItem = isDeleted(node);
167
178
  const isHeroImage = isHeroImageNode(node);
168
- const isTop = isManuscriptNode(parent) && !isHeroImage;
179
+ const isSupplements = isSupplementsNode(node);
180
+ const isMainDocument = isAttachmentsNode(node);
181
+ const editorFiles = isMainDocument
182
+ ? (getFiles?.() ?? getEditorFiles(view))
183
+ : undefined;
184
+ const isTop = isManuscriptNode(parent) &&
185
+ !isHeroImage &&
186
+ !isSupplements &&
187
+ !isMainDocument;
188
+ if (isMainDocument && node.childCount === 0) {
189
+ return null;
190
+ }
191
+ if (isMainDocument) {
192
+ const attachmentIds = new Set();
193
+ node.forEach((childNode) => {
194
+ const href = childNode.attrs?.href;
195
+ if (href) {
196
+ attachmentIds.add(href.replace(/^attachment:/, ''));
197
+ }
198
+ });
199
+ const mainDocumentFile = editorFiles?.find((file) => {
200
+ const fileId = file.id?.replace(/^attachment:/, '');
201
+ return !!fileId && attachmentIds.has(fileId);
202
+ }) ?? editorFiles?.find((file) => isPdfFile(file));
203
+ const isMainDocumentPDF = isPdfFile(mainDocumentFile);
204
+ if (!isMainDocumentPDF) {
205
+ return null;
206
+ }
207
+ }
169
208
  const handleContextMenu = (e) => {
170
209
  e.preventDefault();
171
210
  e.stopPropagation();
@@ -194,15 +233,22 @@ export const DraggableTree = ({ tree, view, depth, can, }) => {
194
233
  }
195
234
  };
196
235
  dragRef(dropRef(ref));
197
- const dragClass = isDragging ? 'dragging' : '';
198
- const dropClass = isOver && dropSide ? `drop-${dropSide}` : '';
199
- const deletedClass = isDeletedItem ? 'deleted' : '';
200
- const heroImageClass = isHeroImage ? 'hero-image' : '';
201
- return (React.createElement(Outline, { ref: ref, className: `${dragClass} ${dropClass} ${deletedClass} ${heroImageClass}` },
202
- !isTop && node.type.name != 'manuscript' && (React.createElement(OutlineItem, { depth: isHeroImage ? 1 : depth, onContextMenu: handleContextMenu, onKeyDown: handleKeyDown, tabIndex: -1, "data-outline-item": true },
236
+ const classNames = [
237
+ isDragging && 'dragging',
238
+ isOver && dropSide && `drop-${dropSide}`,
239
+ isDeletedItem && 'deleted',
240
+ isHeroImage && 'hero-image',
241
+ isSupplements && 'supplements',
242
+ isBibliographySectionNode(node) && 'references',
243
+ isMainDocument && 'main-document',
244
+ ]
245
+ .filter(Boolean)
246
+ .join(' ');
247
+ return (React.createElement(Outline, { ref: ref, className: classNames },
248
+ !isTop && node.type.name != 'manuscript' && (React.createElement(OutlineItem, { depth: isHeroImage || isSupplements || isMainDocument ? 1 : depth, onContextMenu: handleContextMenu, onKeyDown: handleKeyDown, tabIndex: -1, "data-outline-item": true },
203
249
  items.length ? (React.createElement(OutlineItemArrow, { "aria-label": `${isOpen ? 'Collapse' : 'Expand'} ${node.type.name}`, onClick: toggleOpen, tabIndex: -1 }, isOpen ? React.createElement(TriangleExpandedIcon, null) : React.createElement(TriangleCollapsedIcon, null))) : (React.createElement(OutlineItemNoArrow, null)),
204
250
  React.createElement(OutlineItemLink, { to: `#${node.attrs.id}`, tabIndex: -1 },
205
251
  React.createElement(OutlineItemIcon, null, nodeTypeIcon(node.type)),
206
252
  React.createElement(OutlineItemLinkText, { className: `outline-text-${node.type.name}` }, itemText(node))))),
207
- items.length ? (React.createElement("div", { className: `subtree ${isOpen ? '' : 'collapsed'}` }, items.map((subtree, index) => (React.createElement(DraggableTree, { key: subtree.node.attrs.id || 'subtree-' + index, tree: subtree, view: view, depth: !tree.parent ? depth : depth + 1, can: can }))))) : null));
253
+ items.length ? (React.createElement("div", { className: `subtree ${isOpen ? '' : 'collapsed'}` }, items.map((subtree, index) => (React.createElement(DraggableTree, { key: subtree.node.attrs.id || 'subtree-' + index, tree: subtree, view: view, depth: !tree.parent ? depth : depth + 1, can: can, getFiles: getFiles }))))) : null));
208
254
  };
@@ -28,12 +28,12 @@ export const ManuscriptOutline = (props) => {
28
28
  pos: 0,
29
29
  index: 0,
30
30
  });
31
- setValues({ tree, view, can: props.can });
31
+ setValues({ tree, view, can: props.can, getFiles: props.getFiles });
32
32
  }
33
33
  else {
34
34
  setValues(undefined);
35
35
  }
36
- }, [debouncedProps, props.can]);
36
+ }, [debouncedProps, props.can, props.getFiles]);
37
37
  const getOutlineItems = useCallback(() => {
38
38
  if (!containerRef.current)
39
39
  return [];
@@ -120,10 +120,10 @@ export const Outline = styled.div `
120
120
  display: none;
121
121
  }
122
122
 
123
- & .hero-image {
124
- margin-top: 1rem;
125
- padding-top: 0.5rem;
126
- border-top: 1px dashed #ddd;
123
+ & div:has(.supplements, .hero-image, .main-document) .references {
124
+ margin-bottom: 5px;
125
+ padding-bottom: 5px;
126
+ border-bottom: 1px dashed #ddd;
127
127
  }
128
128
  `;
129
129
  export const OutlineItemPlaceholder = styled.span ``;
@@ -13,11 +13,13 @@
13
13
  * See the License for the specific language governing permissions and
14
14
  * limitations under the License.
15
15
  */
16
- import { FileImageIcon, OutlineBlockQuoteIcon, OutlineEmbedIcon, OutlineEquationIcon, OutlineFigureIcon, OutlineManuscriptIcon, OutlineOrderedListIcon, OutlineParagraphIcon, OutlinePullQuoteIcon, OutlineSectionIcon, OutlineTableIcon, OutlineUnorderedListIcon, } from '@manuscripts/style-guide';
16
+ import { FileDocumentIcon, SupplementsIcon, FileImageIcon, OutlineBlockQuoteIcon, OutlineEmbedIcon, OutlineEquationIcon, OutlineFigureIcon, OutlineManuscriptIcon, OutlineOrderedListIcon, OutlineParagraphIcon, OutlinePullQuoteIcon, OutlineSectionIcon, OutlineTableIcon, OutlineUnorderedListIcon, } from '@manuscripts/style-guide';
17
17
  import { schema } from '@manuscripts/transform';
18
18
  import React from 'react';
19
19
  const { nodes } = schema;
20
20
  const OutlineImageIcon = () => (React.createElement(FileImageIcon, { width: "11", height: "14" }));
21
+ const OutlineSupplementsIcon = () => (React.createElement(SupplementsIcon, { width: "11", height: "14" }));
22
+ const OutlineMainDocumentIcon = () => (React.createElement(FileDocumentIcon, { width: "11", height: "14" }));
21
23
  const icons = new Map([
22
24
  [nodes.manuscript, OutlineManuscriptIcon],
23
25
  [nodes.bibliography_section, OutlineSectionIcon],
@@ -33,6 +35,8 @@ const icons = new Map([
33
35
  [nodes.footnotes_section, OutlineSectionIcon],
34
36
  [nodes.image_element, OutlineImageIcon],
35
37
  [nodes.hero_image, OutlineImageIcon],
38
+ [nodes.supplements, OutlineSupplementsIcon],
39
+ [nodes.attachments, OutlineMainDocumentIcon],
36
40
  ]);
37
41
  export const nodeTypeIcon = (nodeType, listType) => {
38
42
  if (nodeType === schema.nodes.list) {
@@ -1,2 +1,2 @@
1
- export const VERSION = '3.7.25';
1
+ export const VERSION = '3.7.27';
2
2
  export const MATHJAX_VERSION = '3.2.2';
@@ -1,6 +1,7 @@
1
1
  import { ManuscriptEditorView, ManuscriptNode } from '@manuscripts/transform';
2
2
  import React from 'react';
3
3
  import { Capabilities } from '../../lib/capabilities';
4
+ import { FileAttachment } from '../../lib/files';
4
5
  export interface TreeItem {
5
6
  index: number;
6
7
  items: TreeItem[];
@@ -22,6 +23,7 @@ export interface DraggableTreeProps {
22
23
  tree: TreeItem;
23
24
  view?: ManuscriptEditorView;
24
25
  can?: Capabilities;
26
+ getFiles?: () => FileAttachment[];
25
27
  }
26
28
  export declare const DraggableTree: React.FC<DraggableTreeProps>;
27
29
  export {};
@@ -16,9 +16,11 @@
16
16
  import { ManuscriptEditorView, ManuscriptNode } from '@manuscripts/transform';
17
17
  import React from 'react';
18
18
  import { Capabilities } from '../../lib/capabilities';
19
+ import { FileAttachment } from '../../lib/files';
19
20
  export interface ManuscriptOutlineProps {
20
21
  doc: ManuscriptNode | null;
21
22
  can?: Capabilities;
22
23
  view?: ManuscriptEditorView;
24
+ getFiles?: () => FileAttachment[];
23
25
  }
24
26
  export declare const ManuscriptOutline: React.FC<ManuscriptOutlineProps>;
@@ -1,2 +1,2 @@
1
- export declare const VERSION = "3.7.25";
1
+ export declare const VERSION = "3.7.27";
2
2
  export declare const MATHJAX_VERSION = "3.2.2";
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": "3.7.25",
4
+ "version": "3.7.27",
5
5
  "repository": "github:Atypon-OpenSource/manuscripts-body-editor",
6
6
  "license": "Apache-2.0",
7
7
  "main": "dist/cjs",
@@ -38,9 +38,9 @@
38
38
  "@citation-js/plugin-ris": "0.7.18",
39
39
  "@iarna/word-count": "1.1.2",
40
40
  "@manuscripts/json-schema": "2.2.12",
41
- "@manuscripts/style-guide": "3.3.13",
41
+ "@manuscripts/style-guide": "3.3.15",
42
42
  "@manuscripts/track-changes-plugin": "2.2.3",
43
- "@manuscripts/transform": "4.3.12",
43
+ "@manuscripts/transform": "4.3.13",
44
44
  "@popperjs/core": "2.11.8",
45
45
  "citeproc": "2.4.63",
46
46
  "codemirror": "5.65.19",