@manuscripts/body-editor 1.13.24 → 1.13.25

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.addRows = exports.insertTableFootnote = exports.addInlineComment = exports.addNodeComment = exports.createAndFillTableElement = exports.selectAllIsolating = exports.ignoreAtomBlockNodeForward = exports.isAtEndOfTextBlock = exports.ignoreMetaNodeBackspaceCommand = exports.ignoreAtomBlockNodeBackward = exports.isTextSelection = exports.isAtStartOfTextBlock = exports.insertTOCSection = exports.insertBibliographySection = exports.insertList = exports.insertKeywords = exports.insertContributors = exports.insertAbstract = exports.insertBackMatterSection = exports.insertSection = exports.insertGraphicalAbstract = exports.insertInlineFootnote = exports.insertFootnote = exports.createFootnote = exports.insertInlineEquation = exports.insertCrossReference = exports.insertInlineCitation = exports.insertLink = exports.insertSectionLabel = exports.insertBreak = exports.deleteBlock = exports.insertBlock = exports.insertFileAsFigure = exports.insertGeneralFootnote = exports.createBlock = exports.createSelection = exports.canInsert = exports.blockActive = exports.isNodeSelection = exports.markActive = void 0;
18
+ exports.addRows = exports.insertTableFootnote = exports.addInlineComment = exports.addNodeComment = exports.createAndFillTableElement = exports.selectAllIsolating = exports.ignoreAtomBlockNodeForward = exports.isAtEndOfTextBlock = exports.ignoreMetaNodeBackspaceCommand = exports.ignoreAtomBlockNodeBackward = exports.isTextSelection = exports.isAtStartOfTextBlock = exports.insertTOCSection = exports.insertBibliographySection = exports.insertList = exports.insertKeywords = exports.insertContributors = exports.insertAbstract = exports.insertBackMatterSection = exports.insertSection = exports.insertGraphicalAbstract = exports.insertInlineFootnote = exports.insertFootnote = exports.createFootnote = exports.insertInlineEquation = exports.insertCrossReference = exports.insertInlineCitation = exports.insertLink = exports.insertSectionLabel = exports.insertBreak = exports.deleteBlock = exports.insertBlock = exports.insertSupplement = exports.insertFigure = exports.insertGeneralFootnote = exports.createBlock = exports.createSelection = exports.canInsert = exports.blockActive = exports.isNodeSelection = exports.markActive = void 0;
19
19
  const json_schema_1 = require("@manuscripts/json-schema");
20
20
  const track_changes_plugin_1 = require("@manuscripts/track-changes-plugin");
21
21
  const transform_1 = require("@manuscripts/transform");
@@ -26,6 +26,7 @@ const prosemirror_tables_1 = require("prosemirror-tables");
26
26
  const prosemirror_transform_1 = require("prosemirror-transform");
27
27
  const prosemirror_utils_1 = require("prosemirror-utils");
28
28
  const comments_1 = require("./lib/comments");
29
+ const doc_1 = require("./lib/doc");
29
30
  const helpers_1 = require("./lib/helpers");
30
31
  const track_changes_utils_1 = require("./lib/track-changes-utils");
31
32
  const utils_1 = require("./lib/utils");
@@ -164,7 +165,7 @@ const insertGeneralFootnote = (tableNode, position, view, tableElementFooter) =>
164
165
  }
165
166
  };
166
167
  exports.insertGeneralFootnote = insertGeneralFootnote;
167
- const insertFileAsFigure = (file, state, dispatch) => {
168
+ const insertFigure = (file, state, dispatch) => {
168
169
  const position = findBlockInsertPosition(state);
169
170
  if (position === null || !dispatch) {
170
171
  return false;
@@ -172,21 +173,34 @@ const insertFileAsFigure = (file, state, dispatch) => {
172
173
  const figure = state.schema.nodes.figure.createAndFill({
173
174
  label: file.name,
174
175
  src: file.id,
175
- embedURL: { default: undefined },
176
- originalURL: { default: undefined },
177
176
  });
178
- const figureElement = state.schema.nodes.figure_element.createAndFill({}, [
177
+ const element = state.schema.nodes.figure_element.createAndFill({}, [
179
178
  figure,
180
179
  state.schema.nodes.figcaption.create({}, [
181
180
  state.schema.nodes.caption_title.create(),
182
181
  state.schema.nodes.caption.create(),
183
182
  ]),
184
183
  ]);
185
- const tr = state.tr.insert(position, figureElement);
184
+ const tr = state.tr.insert(position, element);
186
185
  dispatch(tr);
187
186
  return true;
188
187
  };
189
- exports.insertFileAsFigure = insertFileAsFigure;
188
+ exports.insertFigure = insertFigure;
189
+ const insertSupplement = (file, state, dispatch) => {
190
+ const supplement = transform_1.schema.nodes.supplement.create({
191
+ id: (0, transform_1.generateNodeID)(transform_1.schema.nodes.supplement),
192
+ href: file.id,
193
+ });
194
+ const tr = state.tr;
195
+ const supplements = (0, doc_1.insertSupplementsNode)(tr);
196
+ const pos = supplements.pos + supplements.node.nodeSize - 1;
197
+ tr.insert(pos, supplement);
198
+ if (dispatch) {
199
+ dispatch((0, track_changes_plugin_1.skipTracking)(tr));
200
+ }
201
+ return true;
202
+ };
203
+ exports.insertSupplement = insertSupplement;
190
204
  const insertBlock = (nodeType) => (state, dispatch, view, tableConfig) => {
191
205
  const position = findBlockInsertPosition(state);
192
206
  if (position === null) {
@@ -7,46 +7,47 @@ exports.FigureOptions = exports.FigureElementOptions = void 0;
7
7
  const style_guide_1 = require("@manuscripts/style-guide");
8
8
  const react_1 = __importDefault(require("react"));
9
9
  const styled_components_1 = __importDefault(require("styled-components"));
10
- const FigureElementOptions = ({ can, files, getFilesMap, handleAdd, handleUpload, }) => {
10
+ const FigureElementOptions = ({ can, files, onAdd, onUpload, }) => {
11
11
  const { isOpen, toggleOpen, wrapperRef } = (0, style_guide_1.useDropdown)();
12
- let { supplements, otherFiles } = (0, style_guide_1.useFiles)(getFilesMap(), files);
13
- supplements = supplements.filter(style_guide_1.isImageFile);
14
- otherFiles = otherFiles.filter(style_guide_1.isImageFile);
12
+ const supplements = files.supplements
13
+ .map((s) => s.file)
14
+ .filter((f) => (0, style_guide_1.isImageFile)(f.name));
15
+ const others = files.others.filter((f) => (0, style_guide_1.isImageFile)(f.name));
15
16
  return (react_1.default.createElement(FilesDropdownWrapper, { onClick: toggleOpen, ref: wrapperRef },
16
17
  react_1.default.createElement(FilesButton, null,
17
18
  react_1.default.createElement(style_guide_1.AttachIcon, null)),
18
19
  isOpen && (react_1.default.createElement(style_guide_1.DropdownList, { direction: 'left', width: 208, height: 187, onClick: toggleOpen, top: 7 },
19
- react_1.default.createElement(NestedDropdown, { disabled: !can.replaceFile || supplements.length < 1, parentToggleOpen: toggleOpen, buttonText: 'Supplements', list: react_1.default.createElement(react_1.default.Fragment, null, supplements.map((file) => (react_1.default.createElement(ListItemButton, { key: file.id, onClick: () => handleAdd(file) },
20
- (0, style_guide_1.getFileIcon)(file),
20
+ react_1.default.createElement(NestedDropdown, { disabled: !can.replaceFile || supplements.length < 1, parentToggleOpen: toggleOpen, buttonText: 'Supplements', list: react_1.default.createElement(react_1.default.Fragment, null, supplements.map((file) => (react_1.default.createElement(ListItemButton, { key: file.id, onClick: () => onAdd(file) },
21
+ (0, style_guide_1.getFileIcon)(file.name),
21
22
  react_1.default.createElement(ListItemText, null, file.name))))) }),
22
- react_1.default.createElement(NestedDropdown, { disabled: !can.replaceFile || otherFiles.length < 1, parentToggleOpen: toggleOpen, buttonText: 'Other files', list: react_1.default.createElement(react_1.default.Fragment, null, otherFiles.map((file) => (react_1.default.createElement(ListItemButton, { key: file.id, onClick: () => handleAdd(file) },
23
- (0, style_guide_1.getFileIcon)(file),
23
+ react_1.default.createElement(NestedDropdown, { disabled: !can.replaceFile || others.length < 1, parentToggleOpen: toggleOpen, buttonText: 'Other files', list: react_1.default.createElement(react_1.default.Fragment, null, others.map((file) => (react_1.default.createElement(ListItemButton, { key: file.id, onClick: () => onAdd(file) },
24
+ (0, style_guide_1.getFileIcon)(file.name),
24
25
  react_1.default.createElement(ListItemText, null, file.name))))) }),
25
- react_1.default.createElement(UploadButton, { onClick: handleUpload, disabled: !can.uploadFile },
26
+ react_1.default.createElement(UploadButton, { onClick: onUpload, disabled: !can.uploadFile },
26
27
  react_1.default.createElement(style_guide_1.AddIcon, null),
27
28
  " New file...")))));
28
29
  };
29
30
  exports.FigureElementOptions = FigureElementOptions;
30
- const FigureOptions = ({ can, files, getFilesMap, handleDownload, handleUpload, handleDetach, handleReplace, }) => {
31
+ const FigureOptions = ({ can, files, onDownload, onUpload, onDetach, onReplace, }) => {
31
32
  const { isOpen, toggleOpen, wrapperRef } = (0, style_guide_1.useDropdown)();
32
- const otherFiles = (0, style_guide_1.useFiles)(getFilesMap(), files).otherFiles.filter(style_guide_1.isImageFile);
33
- const showDownload = handleDownload && can.downloadFiles;
34
- const showUpload = handleUpload && can.uploadFile;
35
- const showDetach = handleDetach && can.editArticle;
36
- const showReplace = handleReplace && can.replaceFile;
33
+ const otherFiles = files.others.filter((f) => (0, style_guide_1.isImageFile)(f.name));
34
+ const showDownload = onDownload && can.downloadFiles;
35
+ const showUpload = onUpload && can.uploadFile;
36
+ const showDetach = onDetach && can.editArticle;
37
+ const showReplace = onReplace && can.replaceFile;
37
38
  return (react_1.default.createElement(DropdownWrapper, { ref: wrapperRef },
38
39
  react_1.default.createElement(OptionsButton, { className: 'options-button', onClick: toggleOpen },
39
40
  react_1.default.createElement(style_guide_1.DotsIcon, null)),
40
41
  isOpen && (react_1.default.createElement(OptionsDropdownList, { direction: 'right', width: 128, top: 5 },
41
- react_1.default.createElement(ListItemButton, { onClick: handleDownload, disabled: !showDownload }, "Download"),
42
+ react_1.default.createElement(ListItemButton, { onClick: onDownload, disabled: !showDownload }, "Download"),
42
43
  react_1.default.createElement(NestedDropdown, { disabled: !showReplace, parentToggleOpen: toggleOpen, buttonText: 'Replace', moveLeft: true, list: react_1.default.createElement(react_1.default.Fragment, null,
43
- otherFiles.map((file, index) => (react_1.default.createElement(ListItemButton, { key: file.id, id: index.toString(), onClick: () => handleReplace && handleReplace(file) },
44
- (0, style_guide_1.getFileIcon)(file),
44
+ otherFiles.map((file, index) => (react_1.default.createElement(ListItemButton, { key: file.id, id: index.toString(), onClick: () => onReplace && onReplace(file) },
45
+ (0, style_guide_1.getFileIcon)(file.name),
45
46
  react_1.default.createElement(ListItemText, null, file.name)))),
46
- react_1.default.createElement(UploadButton, { onClick: handleUpload, disabled: !showUpload },
47
+ react_1.default.createElement(UploadButton, { onClick: onUpload, disabled: !showUpload },
47
48
  react_1.default.createElement(style_guide_1.UploadIcon, null),
48
49
  " Upload new...")) }),
49
- react_1.default.createElement(ListItemButton, { onClick: handleDetach, disabled: !showDetach }, "Detach")))));
50
+ react_1.default.createElement(ListItemButton, { onClick: onDetach, disabled: !showDetach }, "Detach")))));
50
51
  };
51
52
  exports.FigureOptions = FigureOptions;
52
53
  const NestedDropdown = ({ parentToggleOpen, buttonText, disabled, list, moveLeft }) => {
package/dist/cjs/index.js CHANGED
@@ -44,6 +44,8 @@ var popper_1 = require("./lib/popper");
44
44
  Object.defineProperty(exports, "PopperManager", { enumerable: true, get: function () { return popper_1.PopperManager; } });
45
45
  __exportStar(require("./toolbar"), exports);
46
46
  __exportStar(require("./lib/comments"), exports);
47
+ __exportStar(require("./lib/files"), exports);
48
+ __exportStar(require("./lib/doc"), exports);
47
49
  __exportStar(require("./plugins/comments"), exports);
48
50
  var selected_suggestion_1 = require("./plugins/selected-suggestion");
49
51
  Object.defineProperty(exports, "selectedSuggestionKey", { enumerable: true, get: function () { return selected_suggestion_1.selectedSuggestionKey; } });
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.findGraphicalAbstractFigureElement = exports.findAbstractsNode = exports.insertSupplementsNode = void 0;
4
+ const transform_1 = require("@manuscripts/transform");
5
+ const prosemirror_utils_1 = require("prosemirror-utils");
6
+ const insertSupplementsNode = (tr) => {
7
+ const doc = tr.doc;
8
+ const supplements = (0, prosemirror_utils_1.findChildrenByType)(doc, transform_1.schema.nodes.supplements)[0];
9
+ if (supplements) {
10
+ return supplements;
11
+ }
12
+ const abstracts = (0, exports.findAbstractsNode)(doc);
13
+ const pos = abstracts.pos - 1;
14
+ tr.insert(pos, transform_1.schema.nodes.supplements.create());
15
+ return {
16
+ node: supplements,
17
+ pos,
18
+ };
19
+ };
20
+ exports.insertSupplementsNode = insertSupplementsNode;
21
+ const findAbstractsNode = (doc) => {
22
+ return (0, prosemirror_utils_1.findChildrenByType)(doc, transform_1.schema.nodes.abstracts)[0];
23
+ };
24
+ exports.findAbstractsNode = findAbstractsNode;
25
+ const findGraphicalAbstractFigureElement = (doc) => {
26
+ const ga = (0, prosemirror_utils_1.findChildrenByType)(doc, transform_1.schema.nodes.graphical_abstract_section)[0];
27
+ if (!ga) {
28
+ return;
29
+ }
30
+ const element = (0, prosemirror_utils_1.findChildrenByType)(ga.node, transform_1.schema.nodes.figure_element)[0];
31
+ if (!element) {
32
+ return;
33
+ }
34
+ return {
35
+ node: element.node,
36
+ pos: ga.pos + element.pos + 1,
37
+ };
38
+ };
39
+ exports.findGraphicalAbstractFigureElement = findGraphicalAbstractFigureElement;
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.groupFiles = void 0;
4
+ const transform_1 = require("@manuscripts/transform");
5
+ const prosemirror_utils_1 = require("prosemirror-utils");
6
+ const doc_1 = require("./doc");
7
+ const track_changes_utils_1 = require("./track-changes-utils");
8
+ const MISSING_FILE = {
9
+ id: '',
10
+ name: 'Missing file',
11
+ type: {
12
+ id: 'missing',
13
+ },
14
+ };
15
+ const groupFiles = (doc, files) => {
16
+ const fileMap = new Map(files.map((f) => [f.id, f]));
17
+ const figures = [];
18
+ const supplements = [];
19
+ const getFigureElementFiles = (node, pos) => {
20
+ const figureFiles = [];
21
+ for (const figure of (0, prosemirror_utils_1.findChildrenByType)(node, transform_1.schema.nodes.figure)) {
22
+ if ((0, track_changes_utils_1.isHidden)(figure.node)) {
23
+ continue;
24
+ }
25
+ const src = (0, track_changes_utils_1.getActualAttrs)(figure.node).src;
26
+ if (!src) {
27
+ continue;
28
+ }
29
+ let file = fileMap.get(src);
30
+ if (file) {
31
+ fileMap.delete(src);
32
+ }
33
+ else {
34
+ file = MISSING_FILE;
35
+ }
36
+ figureFiles.push({
37
+ node: figure.node,
38
+ pos: pos + figure.pos + 1,
39
+ file,
40
+ });
41
+ }
42
+ return {
43
+ node,
44
+ pos,
45
+ files: figureFiles,
46
+ };
47
+ };
48
+ let gaID;
49
+ const element = (0, doc_1.findGraphicalAbstractFigureElement)(doc);
50
+ if (element) {
51
+ gaID = element.node.attrs.id;
52
+ figures.push(getFigureElementFiles(element.node, element.pos));
53
+ }
54
+ doc.descendants((node, pos) => {
55
+ if (node.type === transform_1.schema.nodes.figure_element && node.attrs.id !== gaID) {
56
+ figures.push(getFigureElementFiles(node, pos));
57
+ }
58
+ if (node.type === transform_1.schema.nodes.supplement) {
59
+ if ((0, track_changes_utils_1.isHidden)(node)) {
60
+ return;
61
+ }
62
+ const href = (0, track_changes_utils_1.getActualAttrs)(node).href;
63
+ let file = fileMap.get(href);
64
+ if (file) {
65
+ fileMap.delete(href);
66
+ }
67
+ else {
68
+ file = MISSING_FILE;
69
+ }
70
+ supplements.push({
71
+ node,
72
+ pos,
73
+ file,
74
+ });
75
+ }
76
+ });
77
+ return {
78
+ figures,
79
+ supplements,
80
+ others: [...fileMap.values()],
81
+ };
82
+ };
83
+ exports.groupFiles = groupFiles;
@@ -14,20 +14,8 @@
14
14
  * See the License for the specific language governing permissions and
15
15
  * limitations under the License.
16
16
  */
17
- var __rest = (this && this.__rest) || function (s, e) {
18
- var t = {};
19
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
20
- t[p] = s[p];
21
- if (s != null && typeof Object.getOwnPropertySymbols === "function")
22
- for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
23
- if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
24
- t[p[i]] = s[p[i]];
25
- }
26
- return t;
27
- };
28
17
  Object.defineProperty(exports, "__esModule", { value: true });
29
- exports.buildCitations = exports.getEffectiveAttrs = exports.getLatest = exports.buildDecorations = exports.isBibliographyElement = void 0;
30
- const track_changes_plugin_1 = require("@manuscripts/track-changes-plugin");
18
+ exports.buildCitations = exports.getLatest = exports.buildDecorations = exports.isBibliographyElement = void 0;
31
19
  const prosemirror_view_1 = require("prosemirror-view");
32
20
  const track_changes_utils_1 = require("../../lib/track-changes-utils");
33
21
  const isBibliographyElement = (node) => node.type === node.type.schema.nodes.bibliography_element;
@@ -83,21 +71,6 @@ const buildDecorations = (state, doc) => {
83
71
  exports.buildDecorations = buildDecorations;
84
72
  const getLatest = (a, b) => a.updatedAt > b.updatedAt ? a : b;
85
73
  exports.getLatest = getLatest;
86
- const getEffectiveAttrs = (node, excludeDeletedNode) => {
87
- const _a = node.attrs, { dataTracked } = _a, attrs = __rest(_a, ["dataTracked"]);
88
- const nodeChange = dataTracked === null || dataTracked === void 0 ? void 0 : dataTracked.reduce(exports.getLatest);
89
- const isDeleted = nodeChange &&
90
- nodeChange.operation === track_changes_plugin_1.CHANGE_OPERATION.delete &&
91
- nodeChange.status !== track_changes_plugin_1.CHANGE_STATUS.rejected;
92
- if (isDeleted && excludeDeletedNode) {
93
- return undefined;
94
- }
95
- const isRejected = nodeChange &&
96
- nodeChange.operation === track_changes_plugin_1.CHANGE_OPERATION.set_node_attributes &&
97
- nodeChange.status === track_changes_plugin_1.CHANGE_STATUS.rejected;
98
- return isRejected ? nodeChange === null || nodeChange === void 0 ? void 0 : nodeChange.oldAttrs : attrs;
99
- };
100
- exports.getEffectiveAttrs = getEffectiveAttrs;
101
74
  const buildCitations = (citations) => citations
102
75
  .map((c) => (0, track_changes_utils_1.getActualAttrs)(c[0]))
103
76
  .map((attrs) => ({
@@ -32,7 +32,7 @@ const style_guide_1 = require("@manuscripts/style-guide");
32
32
  const react_1 = require("react");
33
33
  const react_dom_1 = __importDefault(require("react-dom"));
34
34
  const FigureDropdown_1 = require("../components/views/FigureDropdown");
35
- const build_file_models_1 = require("../lib/build-file-models");
35
+ const files_1 = require("../lib/files");
36
36
  const track_changes_utils_1 = require("../lib/track-changes-utils");
37
37
  const creators_1 = require("./creators");
38
38
  const figure_1 = require("./figure");
@@ -54,19 +54,18 @@ class FigureEditableView extends figure_1.FigureView {
54
54
  var _a, _b;
55
55
  const attrs = (0, track_changes_utils_1.getActualAttrs)(this.node);
56
56
  if ((_a = this.node.attrs.dataTracked) === null || _a === void 0 ? void 0 : _a.length) {
57
- this.dom.setAttribute('data-track-status', this.node.attrs.dataTracked[0].status);
58
- this.dom.setAttribute('data-track-op', this.node.attrs.dataTracked[0].operation);
57
+ const change = this.node.attrs.dataTracked[0];
58
+ this.dom.setAttribute('data-track-status', change.status);
59
+ this.dom.setAttribute('data-track-op', change.operation);
59
60
  }
60
61
  else {
61
62
  this.dom.removeAttribute('data-track-status');
62
- this.dom.removeAttribute('data-track-type');
63
+ this.dom.removeAttribute('data-track-op');
63
64
  }
64
65
  const src = attrs.src;
65
66
  const files = this.props.getFiles();
66
67
  const file = src && files.filter((f) => f.id === src)[0];
67
- while (this.container.hasChildNodes()) {
68
- this.container.removeChild(this.container.firstChild);
69
- }
68
+ this.container.innerHTML = '';
70
69
  const can = this.props.getCapabilities();
71
70
  const link = file && this.props.fileManagement.previewLink(file);
72
71
  const img = link
@@ -132,14 +131,15 @@ class FigureEditableView extends figure_1.FigureView {
132
131
  this.container.appendChild(img);
133
132
  (_b = this.reactTools) === null || _b === void 0 ? void 0 : _b.remove();
134
133
  if (this.props.dispatch && this.props.theme) {
134
+ const files = this.props.getFiles();
135
+ const doc = this.view.state.doc;
135
136
  const componentProps = {
136
137
  can,
137
- files,
138
- getFilesMap: () => (0, build_file_models_1.buildFileMap)(this.view.state.doc),
139
- handleDownload,
140
- handleUpload,
141
- handleDetach,
142
- handleReplace,
138
+ files: (0, files_1.groupFiles)(doc, files),
139
+ onDownload: handleDownload,
140
+ onUpload: handleUpload,
141
+ onDetach: handleDetach,
142
+ onReplace: handleReplace,
143
143
  };
144
144
  this.reactTools = (0, ReactSubView_1.default)(this.props, FigureDropdown_1.FigureOptions, componentProps, this.node, this.getPos, this.view);
145
145
  this.dom.insertBefore(this.reactTools, this.dom.firstChild);
@@ -30,7 +30,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
30
30
  exports.FigureElementView = void 0;
31
31
  const transform_1 = require("@manuscripts/transform");
32
32
  const FigureDropdown_1 = require("../components/views/FigureDropdown");
33
- const build_file_models_1 = require("../lib/build-file-models");
33
+ const files_1 = require("../lib/files");
34
34
  const utils_1 = require("../lib/utils");
35
35
  const block_view_1 = __importDefault(require("./block_view"));
36
36
  const creators_1 = require("./creators");
@@ -56,12 +56,13 @@ class FigureElementView extends block_view_1.default {
56
56
  throw new Error('No contentDOM');
57
57
  }
58
58
  if ((_a = this.node.attrs.dataTracked) === null || _a === void 0 ? void 0 : _a.length) {
59
- this.dom.setAttribute('data-track-status', this.node.attrs.dataTracked[0].status);
60
- this.dom.setAttribute('data-track-op', this.node.attrs.dataTracked[0].operation);
59
+ const change = this.node.attrs.dataTracked[0];
60
+ this.dom.setAttribute('data-track-status', change.status);
61
+ this.dom.setAttribute('data-track-op', change.operation);
61
62
  }
62
63
  else {
63
64
  this.dom.removeAttribute('data-track-status');
64
- this.dom.removeAttribute('data-track-type');
65
+ this.dom.removeAttribute('data-track-op');
65
66
  }
66
67
  this.contentDOM.setAttribute('data-figure-style', figureStyle);
67
68
  this.contentDOM.setAttribute('data-figure-layout', figureLayout);
@@ -107,12 +108,13 @@ class FigureElementView extends block_view_1.default {
107
108
  handleUpload = (0, figure_uploader_1.figureUploader)(upload);
108
109
  }
109
110
  if (this.props.dispatch && this.props.theme) {
111
+ const files = this.props.getFiles();
112
+ const doc = this.view.state.doc;
110
113
  const componentProps = {
111
114
  can: can,
112
- files: this.props.getFiles(),
113
- getFilesMap: () => (0, build_file_models_1.buildFileMap)(this.view.state.doc),
114
- handleUpload,
115
- handleAdd,
115
+ files: (0, files_1.groupFiles)(doc, files),
116
+ onUpload: handleUpload,
117
+ onAdd: handleAdd,
116
118
  };
117
119
  this.reactTools = (0, ReactSubView_1.default)(this.props, FigureDropdown_1.FigureElementOptions, componentProps, this.node, this.getPos, this.view);
118
120
  (_b = this.reactTools) === null || _b === void 0 ? void 0 : _b.remove();
@@ -15,7 +15,7 @@
15
15
  */
16
16
  import { buildContribution, ObjectTypes } from '@manuscripts/json-schema';
17
17
  import { skipTracking } from '@manuscripts/track-changes-plugin';
18
- import { generateID, isElementNodeType, isFootnoteNode, isInBibliographySection, isListNode, isParagraphNode, isSectionNodeType, schema, } from '@manuscripts/transform';
18
+ import { generateID, generateNodeID, isElementNodeType, isFootnoteNode, isInBibliographySection, isListNode, isParagraphNode, isSectionNodeType, schema, } from '@manuscripts/transform';
19
19
  import { Fragment, NodeRange, } from 'prosemirror-model';
20
20
  import { wrapInList } from 'prosemirror-schema-list';
21
21
  import { NodeSelection, TextSelection, } from 'prosemirror-state';
@@ -23,6 +23,7 @@ import { addRow, isInTable, selectedRect } from 'prosemirror-tables';
23
23
  import { findWrapping, liftTarget, ReplaceAroundStep, } from 'prosemirror-transform';
24
24
  import { findChildrenByType, findParentNodeOfType, findParentNodeOfTypeClosestToPos, } from 'prosemirror-utils';
25
25
  import { getCommentKey, getCommentRange } from './lib/comments';
26
+ import { insertSupplementsNode } from './lib/doc';
26
27
  import { isNodeOfType, nearestAncestor } from './lib/helpers';
27
28
  import { isDeleted, isRejectedInsert } from './lib/track-changes-utils';
28
29
  import { findParentNodeWithId, getChildOfType, getMatchingChild, } from './lib/utils';
@@ -154,7 +155,7 @@ export const insertGeneralFootnote = (tableNode, position, view, tableElementFoo
154
155
  dispatch(tr.setSelection(selection).scrollIntoView());
155
156
  }
156
157
  };
157
- export const insertFileAsFigure = (file, state, dispatch) => {
158
+ export const insertFigure = (file, state, dispatch) => {
158
159
  const position = findBlockInsertPosition(state);
159
160
  if (position === null || !dispatch) {
160
161
  return false;
@@ -162,20 +163,32 @@ export const insertFileAsFigure = (file, state, dispatch) => {
162
163
  const figure = state.schema.nodes.figure.createAndFill({
163
164
  label: file.name,
164
165
  src: file.id,
165
- embedURL: { default: undefined },
166
- originalURL: { default: undefined },
167
166
  });
168
- const figureElement = state.schema.nodes.figure_element.createAndFill({}, [
167
+ const element = state.schema.nodes.figure_element.createAndFill({}, [
169
168
  figure,
170
169
  state.schema.nodes.figcaption.create({}, [
171
170
  state.schema.nodes.caption_title.create(),
172
171
  state.schema.nodes.caption.create(),
173
172
  ]),
174
173
  ]);
175
- const tr = state.tr.insert(position, figureElement);
174
+ const tr = state.tr.insert(position, element);
176
175
  dispatch(tr);
177
176
  return true;
178
177
  };
178
+ export const insertSupplement = (file, state, dispatch) => {
179
+ const supplement = schema.nodes.supplement.create({
180
+ id: generateNodeID(schema.nodes.supplement),
181
+ href: file.id,
182
+ });
183
+ const tr = state.tr;
184
+ const supplements = insertSupplementsNode(tr);
185
+ const pos = supplements.pos + supplements.node.nodeSize - 1;
186
+ tr.insert(pos, supplement);
187
+ if (dispatch) {
188
+ dispatch(skipTracking(tr));
189
+ }
190
+ return true;
191
+ };
179
192
  export const insertBlock = (nodeType) => (state, dispatch, view, tableConfig) => {
180
193
  const position = findBlockInsertPosition(state);
181
194
  if (position === null) {
@@ -1,45 +1,46 @@
1
- import { AddIcon, AttachIcon, DotsIcon, DropdownList, getFileIcon, IconButton, IconTextButton, isImageFile, RoundIconButton, TriangleCollapsedIcon, UploadIcon, useDropdown, useFiles, } from '@manuscripts/style-guide';
1
+ import { AddIcon, AttachIcon, DotsIcon, DropdownList, getFileIcon, IconButton, IconTextButton, isImageFile, RoundIconButton, TriangleCollapsedIcon, UploadIcon, useDropdown, } from '@manuscripts/style-guide';
2
2
  import React from 'react';
3
3
  import styled from 'styled-components';
4
- export const FigureElementOptions = ({ can, files, getFilesMap, handleAdd, handleUpload, }) => {
4
+ export const FigureElementOptions = ({ can, files, onAdd, onUpload, }) => {
5
5
  const { isOpen, toggleOpen, wrapperRef } = useDropdown();
6
- let { supplements, otherFiles } = useFiles(getFilesMap(), files);
7
- supplements = supplements.filter(isImageFile);
8
- otherFiles = otherFiles.filter(isImageFile);
6
+ const supplements = files.supplements
7
+ .map((s) => s.file)
8
+ .filter((f) => isImageFile(f.name));
9
+ const others = files.others.filter((f) => isImageFile(f.name));
9
10
  return (React.createElement(FilesDropdownWrapper, { onClick: toggleOpen, ref: wrapperRef },
10
11
  React.createElement(FilesButton, null,
11
12
  React.createElement(AttachIcon, null)),
12
13
  isOpen && (React.createElement(DropdownList, { direction: 'left', width: 208, height: 187, onClick: toggleOpen, top: 7 },
13
- React.createElement(NestedDropdown, { disabled: !can.replaceFile || supplements.length < 1, parentToggleOpen: toggleOpen, buttonText: 'Supplements', list: React.createElement(React.Fragment, null, supplements.map((file) => (React.createElement(ListItemButton, { key: file.id, onClick: () => handleAdd(file) },
14
- getFileIcon(file),
14
+ React.createElement(NestedDropdown, { disabled: !can.replaceFile || supplements.length < 1, parentToggleOpen: toggleOpen, buttonText: 'Supplements', list: React.createElement(React.Fragment, null, supplements.map((file) => (React.createElement(ListItemButton, { key: file.id, onClick: () => onAdd(file) },
15
+ getFileIcon(file.name),
15
16
  React.createElement(ListItemText, null, file.name))))) }),
16
- React.createElement(NestedDropdown, { disabled: !can.replaceFile || otherFiles.length < 1, parentToggleOpen: toggleOpen, buttonText: 'Other files', list: React.createElement(React.Fragment, null, otherFiles.map((file) => (React.createElement(ListItemButton, { key: file.id, onClick: () => handleAdd(file) },
17
- getFileIcon(file),
17
+ React.createElement(NestedDropdown, { disabled: !can.replaceFile || others.length < 1, parentToggleOpen: toggleOpen, buttonText: 'Other files', list: React.createElement(React.Fragment, null, others.map((file) => (React.createElement(ListItemButton, { key: file.id, onClick: () => onAdd(file) },
18
+ getFileIcon(file.name),
18
19
  React.createElement(ListItemText, null, file.name))))) }),
19
- React.createElement(UploadButton, { onClick: handleUpload, disabled: !can.uploadFile },
20
+ React.createElement(UploadButton, { onClick: onUpload, disabled: !can.uploadFile },
20
21
  React.createElement(AddIcon, null),
21
22
  " New file...")))));
22
23
  };
23
- export const FigureOptions = ({ can, files, getFilesMap, handleDownload, handleUpload, handleDetach, handleReplace, }) => {
24
+ export const FigureOptions = ({ can, files, onDownload, onUpload, onDetach, onReplace, }) => {
24
25
  const { isOpen, toggleOpen, wrapperRef } = useDropdown();
25
- const otherFiles = useFiles(getFilesMap(), files).otherFiles.filter(isImageFile);
26
- const showDownload = handleDownload && can.downloadFiles;
27
- const showUpload = handleUpload && can.uploadFile;
28
- const showDetach = handleDetach && can.editArticle;
29
- const showReplace = handleReplace && can.replaceFile;
26
+ const otherFiles = files.others.filter((f) => isImageFile(f.name));
27
+ const showDownload = onDownload && can.downloadFiles;
28
+ const showUpload = onUpload && can.uploadFile;
29
+ const showDetach = onDetach && can.editArticle;
30
+ const showReplace = onReplace && can.replaceFile;
30
31
  return (React.createElement(DropdownWrapper, { ref: wrapperRef },
31
32
  React.createElement(OptionsButton, { className: 'options-button', onClick: toggleOpen },
32
33
  React.createElement(DotsIcon, null)),
33
34
  isOpen && (React.createElement(OptionsDropdownList, { direction: 'right', width: 128, top: 5 },
34
- React.createElement(ListItemButton, { onClick: handleDownload, disabled: !showDownload }, "Download"),
35
+ React.createElement(ListItemButton, { onClick: onDownload, disabled: !showDownload }, "Download"),
35
36
  React.createElement(NestedDropdown, { disabled: !showReplace, parentToggleOpen: toggleOpen, buttonText: 'Replace', moveLeft: true, list: React.createElement(React.Fragment, null,
36
- otherFiles.map((file, index) => (React.createElement(ListItemButton, { key: file.id, id: index.toString(), onClick: () => handleReplace && handleReplace(file) },
37
- getFileIcon(file),
37
+ otherFiles.map((file, index) => (React.createElement(ListItemButton, { key: file.id, id: index.toString(), onClick: () => onReplace && onReplace(file) },
38
+ getFileIcon(file.name),
38
39
  React.createElement(ListItemText, null, file.name)))),
39
- React.createElement(UploadButton, { onClick: handleUpload, disabled: !showUpload },
40
+ React.createElement(UploadButton, { onClick: onUpload, disabled: !showUpload },
40
41
  React.createElement(UploadIcon, null),
41
42
  " Upload new...")) }),
42
- React.createElement(ListItemButton, { onClick: handleDetach, disabled: !showDetach }, "Detach")))));
43
+ React.createElement(ListItemButton, { onClick: onDetach, disabled: !showDetach }, "Detach")))));
43
44
  };
44
45
  const NestedDropdown = ({ parentToggleOpen, buttonText, disabled, list, moveLeft }) => {
45
46
  const { isOpen, toggleOpen, wrapperRef } = useDropdown();
package/dist/es/index.js CHANGED
@@ -22,6 +22,8 @@ export { CollabProvider } from './classes/collabProvider';
22
22
  export { PopperManager } from './lib/popper';
23
23
  export * from './toolbar';
24
24
  export * from './lib/comments';
25
+ export * from './lib/files';
26
+ export * from './lib/doc';
25
27
  export * from './plugins/comments';
26
28
  export { selectedSuggestionKey } from './plugins/selected-suggestion';
27
29
  export * from './lib/utils';
@@ -0,0 +1,33 @@
1
+ import { schema, } from '@manuscripts/transform';
2
+ import { findChildrenByType } from 'prosemirror-utils';
3
+ export const insertSupplementsNode = (tr) => {
4
+ const doc = tr.doc;
5
+ const supplements = findChildrenByType(doc, schema.nodes.supplements)[0];
6
+ if (supplements) {
7
+ return supplements;
8
+ }
9
+ const abstracts = findAbstractsNode(doc);
10
+ const pos = abstracts.pos - 1;
11
+ tr.insert(pos, schema.nodes.supplements.create());
12
+ return {
13
+ node: supplements,
14
+ pos,
15
+ };
16
+ };
17
+ export const findAbstractsNode = (doc) => {
18
+ return findChildrenByType(doc, schema.nodes.abstracts)[0];
19
+ };
20
+ export const findGraphicalAbstractFigureElement = (doc) => {
21
+ const ga = findChildrenByType(doc, schema.nodes.graphical_abstract_section)[0];
22
+ if (!ga) {
23
+ return;
24
+ }
25
+ const element = findChildrenByType(ga.node, schema.nodes.figure_element)[0];
26
+ if (!element) {
27
+ return;
28
+ }
29
+ return {
30
+ node: element.node,
31
+ pos: ga.pos + element.pos + 1,
32
+ };
33
+ };
@@ -0,0 +1,79 @@
1
+ import { schema } from '@manuscripts/transform';
2
+ import { findChildrenByType } from 'prosemirror-utils';
3
+ import { findGraphicalAbstractFigureElement } from './doc';
4
+ import { getActualAttrs, isHidden } from './track-changes-utils';
5
+ const MISSING_FILE = {
6
+ id: '',
7
+ name: 'Missing file',
8
+ type: {
9
+ id: 'missing',
10
+ },
11
+ };
12
+ export const groupFiles = (doc, files) => {
13
+ const fileMap = new Map(files.map((f) => [f.id, f]));
14
+ const figures = [];
15
+ const supplements = [];
16
+ const getFigureElementFiles = (node, pos) => {
17
+ const figureFiles = [];
18
+ for (const figure of findChildrenByType(node, schema.nodes.figure)) {
19
+ if (isHidden(figure.node)) {
20
+ continue;
21
+ }
22
+ const src = getActualAttrs(figure.node).src;
23
+ if (!src) {
24
+ continue;
25
+ }
26
+ let file = fileMap.get(src);
27
+ if (file) {
28
+ fileMap.delete(src);
29
+ }
30
+ else {
31
+ file = MISSING_FILE;
32
+ }
33
+ figureFiles.push({
34
+ node: figure.node,
35
+ pos: pos + figure.pos + 1,
36
+ file,
37
+ });
38
+ }
39
+ return {
40
+ node,
41
+ pos,
42
+ files: figureFiles,
43
+ };
44
+ };
45
+ let gaID;
46
+ const element = findGraphicalAbstractFigureElement(doc);
47
+ if (element) {
48
+ gaID = element.node.attrs.id;
49
+ figures.push(getFigureElementFiles(element.node, element.pos));
50
+ }
51
+ doc.descendants((node, pos) => {
52
+ if (node.type === schema.nodes.figure_element && node.attrs.id !== gaID) {
53
+ figures.push(getFigureElementFiles(node, pos));
54
+ }
55
+ if (node.type === schema.nodes.supplement) {
56
+ if (isHidden(node)) {
57
+ return;
58
+ }
59
+ const href = getActualAttrs(node).href;
60
+ let file = fileMap.get(href);
61
+ if (file) {
62
+ fileMap.delete(href);
63
+ }
64
+ else {
65
+ file = MISSING_FILE;
66
+ }
67
+ supplements.push({
68
+ node,
69
+ pos,
70
+ file,
71
+ });
72
+ }
73
+ });
74
+ return {
75
+ figures,
76
+ supplements,
77
+ others: [...fileMap.values()],
78
+ };
79
+ };
@@ -13,18 +13,6 @@
13
13
  * See the License for the specific language governing permissions and
14
14
  * limitations under the License.
15
15
  */
16
- var __rest = (this && this.__rest) || function (s, e) {
17
- var t = {};
18
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
19
- t[p] = s[p];
20
- if (s != null && typeof Object.getOwnPropertySymbols === "function")
21
- for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
22
- if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
23
- t[p[i]] = s[p[i]];
24
- }
25
- return t;
26
- };
27
- import { CHANGE_OPERATION, CHANGE_STATUS, } from '@manuscripts/track-changes-plugin';
28
16
  import { Decoration } from 'prosemirror-view';
29
17
  import { getActualAttrs } from '../../lib/track-changes-utils';
30
18
  export const isBibliographyElement = (node) => node.type === node.type.schema.nodes.bibliography_element;
@@ -77,20 +65,6 @@ export const buildDecorations = (state, doc) => {
77
65
  return decorations;
78
66
  };
79
67
  export const getLatest = (a, b) => a.updatedAt > b.updatedAt ? a : b;
80
- export const getEffectiveAttrs = (node, excludeDeletedNode) => {
81
- const _a = node.attrs, { dataTracked } = _a, attrs = __rest(_a, ["dataTracked"]);
82
- const nodeChange = dataTracked === null || dataTracked === void 0 ? void 0 : dataTracked.reduce(getLatest);
83
- const isDeleted = nodeChange &&
84
- nodeChange.operation === CHANGE_OPERATION.delete &&
85
- nodeChange.status !== CHANGE_STATUS.rejected;
86
- if (isDeleted && excludeDeletedNode) {
87
- return undefined;
88
- }
89
- const isRejected = nodeChange &&
90
- nodeChange.operation === CHANGE_OPERATION.set_node_attributes &&
91
- nodeChange.status === CHANGE_STATUS.rejected;
92
- return isRejected ? nodeChange === null || nodeChange === void 0 ? void 0 : nodeChange.oldAttrs : attrs;
93
- };
94
68
  export const buildCitations = (citations) => citations
95
69
  .map((c) => getActualAttrs(c[0]))
96
70
  .map((attrs) => ({
@@ -22,11 +22,11 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
22
22
  step((generator = generator.apply(thisArg, _arguments || [])).next());
23
23
  });
24
24
  };
25
- import { FileCorruptedIcon, } from '@manuscripts/style-guide';
25
+ import { FileCorruptedIcon } from '@manuscripts/style-guide';
26
26
  import { createElement } from 'react';
27
27
  import ReactDOM from 'react-dom';
28
28
  import { FigureOptions, } from '../components/views/FigureDropdown';
29
- import { buildFileMap } from '../lib/build-file-models';
29
+ import { groupFiles } from '../lib/files';
30
30
  import { getActualAttrs } from '../lib/track-changes-utils';
31
31
  import { createEditableNodeView } from './creators';
32
32
  import { FigureView } from './figure';
@@ -48,19 +48,18 @@ export class FigureEditableView extends FigureView {
48
48
  var _a, _b;
49
49
  const attrs = getActualAttrs(this.node);
50
50
  if ((_a = this.node.attrs.dataTracked) === null || _a === void 0 ? void 0 : _a.length) {
51
- this.dom.setAttribute('data-track-status', this.node.attrs.dataTracked[0].status);
52
- this.dom.setAttribute('data-track-op', this.node.attrs.dataTracked[0].operation);
51
+ const change = this.node.attrs.dataTracked[0];
52
+ this.dom.setAttribute('data-track-status', change.status);
53
+ this.dom.setAttribute('data-track-op', change.operation);
53
54
  }
54
55
  else {
55
56
  this.dom.removeAttribute('data-track-status');
56
- this.dom.removeAttribute('data-track-type');
57
+ this.dom.removeAttribute('data-track-op');
57
58
  }
58
59
  const src = attrs.src;
59
60
  const files = this.props.getFiles();
60
61
  const file = src && files.filter((f) => f.id === src)[0];
61
- while (this.container.hasChildNodes()) {
62
- this.container.removeChild(this.container.firstChild);
63
- }
62
+ this.container.innerHTML = '';
64
63
  const can = this.props.getCapabilities();
65
64
  const link = file && this.props.fileManagement.previewLink(file);
66
65
  const img = link
@@ -126,14 +125,15 @@ export class FigureEditableView extends FigureView {
126
125
  this.container.appendChild(img);
127
126
  (_b = this.reactTools) === null || _b === void 0 ? void 0 : _b.remove();
128
127
  if (this.props.dispatch && this.props.theme) {
128
+ const files = this.props.getFiles();
129
+ const doc = this.view.state.doc;
129
130
  const componentProps = {
130
131
  can,
131
- files,
132
- getFilesMap: () => buildFileMap(this.view.state.doc),
133
- handleDownload,
134
- handleUpload,
135
- handleDetach,
136
- handleReplace,
132
+ files: groupFiles(doc, files),
133
+ onDownload: handleDownload,
134
+ onUpload: handleUpload,
135
+ onDetach: handleDetach,
136
+ onReplace: handleReplace,
137
137
  };
138
138
  this.reactTools = ReactSubView(this.props, FigureOptions, componentProps, this.node, this.getPos, this.view);
139
139
  this.dom.insertBefore(this.reactTools, this.dom.firstChild);
@@ -24,7 +24,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
24
24
  };
25
25
  import { schema } from '@manuscripts/transform';
26
26
  import { FigureElementOptions, } from '../components/views/FigureDropdown';
27
- import { buildFileMap } from '../lib/build-file-models';
27
+ import { groupFiles } from '../lib/files';
28
28
  import { getMatchingChild } from '../lib/utils';
29
29
  import BlockView from './block_view';
30
30
  import { createNodeView } from './creators';
@@ -50,12 +50,13 @@ export class FigureElementView extends BlockView {
50
50
  throw new Error('No contentDOM');
51
51
  }
52
52
  if ((_a = this.node.attrs.dataTracked) === null || _a === void 0 ? void 0 : _a.length) {
53
- this.dom.setAttribute('data-track-status', this.node.attrs.dataTracked[0].status);
54
- this.dom.setAttribute('data-track-op', this.node.attrs.dataTracked[0].operation);
53
+ const change = this.node.attrs.dataTracked[0];
54
+ this.dom.setAttribute('data-track-status', change.status);
55
+ this.dom.setAttribute('data-track-op', change.operation);
55
56
  }
56
57
  else {
57
58
  this.dom.removeAttribute('data-track-status');
58
- this.dom.removeAttribute('data-track-type');
59
+ this.dom.removeAttribute('data-track-op');
59
60
  }
60
61
  this.contentDOM.setAttribute('data-figure-style', figureStyle);
61
62
  this.contentDOM.setAttribute('data-figure-layout', figureLayout);
@@ -101,12 +102,13 @@ export class FigureElementView extends BlockView {
101
102
  handleUpload = figureUploader(upload);
102
103
  }
103
104
  if (this.props.dispatch && this.props.theme) {
105
+ const files = this.props.getFiles();
106
+ const doc = this.view.state.doc;
104
107
  const componentProps = {
105
108
  can: can,
106
- files: this.props.getFiles(),
107
- getFilesMap: () => buildFileMap(this.view.state.doc),
108
- handleUpload,
109
- handleAdd,
109
+ files: groupFiles(doc, files),
110
+ onUpload: handleUpload,
111
+ onAdd: handleAdd,
110
112
  };
111
113
  this.reactTools = ReactSubView(this.props, FigureElementOptions, componentProps, this.node, this.getPos, this.view);
112
114
  (_b = this.reactTools) === null || _b === void 0 ? void 0 : _b.remove();
@@ -13,12 +13,13 @@
13
13
  * See the License for the specific language governing permissions and
14
14
  * limitations under the License.
15
15
  */
16
- import { FileAttachment, TableConfig } from '@manuscripts/style-guide';
16
+ import { TableConfig } from '@manuscripts/style-guide';
17
17
  import { FootnoteNode, InlineFootnoteNode, ManuscriptEditorState, ManuscriptEditorView, ManuscriptMarkType, ManuscriptNode, ManuscriptNodeType, ManuscriptTransaction } from '@manuscripts/transform';
18
18
  import { Attrs, ResolvedPos } from 'prosemirror-model';
19
19
  import { EditorState, NodeSelection, Selection, TextSelection, Transaction } from 'prosemirror-state';
20
20
  import { NodeWithPos } from 'prosemirror-utils';
21
21
  import { EditorView } from 'prosemirror-view';
22
+ import { FileAttachment } from './lib/files';
22
23
  import { EditorAction } from './types';
23
24
  export type Dispatch = (tr: ManuscriptTransaction) => void;
24
25
  export declare const markActive: (type: ManuscriptMarkType) => (state: ManuscriptEditorState) => boolean;
@@ -28,7 +29,8 @@ export declare const canInsert: (type: ManuscriptNodeType) => (state: Manuscript
28
29
  export declare const createSelection: (nodeType: ManuscriptNodeType, position: number, doc: ManuscriptNode) => Selection;
29
30
  export declare const createBlock: (nodeType: ManuscriptNodeType, position: number, state: ManuscriptEditorState, dispatch?: Dispatch, attrs?: Attrs, tableConfig?: TableConfig) => void;
30
31
  export declare const insertGeneralFootnote: (tableNode: ManuscriptNode, position: number, view: ManuscriptEditorView, tableElementFooter?: NodeWithPos[]) => void;
31
- export declare const insertFileAsFigure: (file: FileAttachment, state: ManuscriptEditorState, dispatch?: Dispatch) => boolean;
32
+ export declare const insertFigure: (file: FileAttachment, state: ManuscriptEditorState, dispatch?: Dispatch) => boolean;
33
+ export declare const insertSupplement: (file: FileAttachment, state: ManuscriptEditorState, dispatch?: Dispatch) => boolean;
32
34
  export declare const insertBlock: (nodeType: ManuscriptNodeType) => (state: ManuscriptEditorState, dispatch?: Dispatch, view?: EditorView, tableConfig?: TableConfig) => boolean;
33
35
  export declare const deleteBlock: (typeToDelete: string) => (state: ManuscriptEditorState, dispatch?: Dispatch) => boolean;
34
36
  export declare const insertBreak: EditorAction;
@@ -1,20 +1,19 @@
1
- import { Model } from '@manuscripts/json-schema';
2
- import { Capabilities, FileAttachment } from '@manuscripts/style-guide';
1
+ import { Capabilities } from '@manuscripts/style-guide';
3
2
  import React from 'react';
3
+ import { FileAttachment, ManuscriptFiles } from '../../lib/files';
4
4
  export interface FigureDropdownProps {
5
5
  can: Capabilities;
6
- files: FileAttachment[];
7
- getFilesMap: () => Map<string, Model>;
6
+ files: ManuscriptFiles;
8
7
  }
9
8
  export interface FigureOptionsProps extends FigureDropdownProps {
10
- handleDownload?: () => void;
11
- handleUpload?: () => void;
12
- handleDetach?: () => void;
13
- handleReplace?: (file: FileAttachment) => void;
9
+ onDownload?: () => void;
10
+ onUpload?: () => void;
11
+ onDetach?: () => void;
12
+ onReplace?: (file: FileAttachment) => void;
14
13
  }
15
14
  export interface FigureElementOptionsProps extends FigureDropdownProps {
16
- handleAdd: (file: FileAttachment) => Promise<void>;
17
- handleUpload: () => void;
15
+ onAdd: (file: FileAttachment) => Promise<void>;
16
+ onUpload: () => void;
18
17
  }
19
18
  export declare const FigureElementOptions: React.FC<FigureElementOptionsProps>;
20
19
  export declare const FigureOptions: React.FC<FigureOptionsProps>;
@@ -15,7 +15,7 @@
15
15
  */
16
16
  import 'prosemirror-view/style/prosemirror.css';
17
17
  import { Manuscript, UserProfile } from '@manuscripts/json-schema';
18
- import { Capabilities, FileAttachment, FileManagement } from '@manuscripts/style-guide';
18
+ import { Capabilities } from '@manuscripts/style-guide';
19
19
  import { ManuscriptNode } from '@manuscripts/transform';
20
20
  import { History } from 'history';
21
21
  import { EditorState } from 'prosemirror-state';
@@ -23,6 +23,7 @@ import { EditorView } from 'prosemirror-view';
23
23
  import { DefaultTheme } from 'styled-components';
24
24
  import { CollabProvider } from '../classes/collabProvider';
25
25
  import { Dispatch } from '../commands';
26
+ import { FileAttachment, FileManagement } from '../lib/files';
26
27
  import { PopperManager } from '../lib/popper';
27
28
  export type CSLProps = {
28
29
  style?: string;
@@ -23,6 +23,8 @@ export { CollabProvider } from './classes/collabProvider';
23
23
  export { PopperManager } from './lib/popper';
24
24
  export * from './toolbar';
25
25
  export * from './lib/comments';
26
+ export * from './lib/files';
27
+ export * from './lib/doc';
26
28
  export * from './plugins/comments';
27
29
  export { selectedSuggestionKey } from './plugins/selected-suggestion';
28
30
  export * from './lib/utils';
@@ -0,0 +1,7 @@
1
+ import { ManuscriptNode, ManuscriptTransaction } from '@manuscripts/transform';
2
+ export declare const insertSupplementsNode: (tr: ManuscriptTransaction) => import("prosemirror-utils").NodeWithPos;
3
+ export declare const findAbstractsNode: (doc: ManuscriptNode) => import("prosemirror-utils").NodeWithPos;
4
+ export declare const findGraphicalAbstractFigureElement: (doc: ManuscriptNode) => {
5
+ node: import("prosemirror-model").Node;
6
+ pos: number;
7
+ } | undefined;
@@ -0,0 +1,34 @@
1
+ import { ManuscriptNode } from '@manuscripts/transform';
2
+ export type FileDesignation = {
3
+ id: string;
4
+ };
5
+ export type FileAttachment = {
6
+ id: string;
7
+ name: string;
8
+ type: FileDesignation;
9
+ createdDate?: Date;
10
+ };
11
+ export type NodeFile = {
12
+ node: ManuscriptNode;
13
+ pos: number;
14
+ file: FileAttachment;
15
+ };
16
+ export type ElementFiles = {
17
+ node: ManuscriptNode;
18
+ pos: number;
19
+ files: NodeFile[];
20
+ };
21
+ export type ManuscriptFiles = {
22
+ figures: ElementFiles[];
23
+ supplements: NodeFile[];
24
+ others: FileAttachment[];
25
+ };
26
+ export type Upload = (file: File) => Promise<FileAttachment>;
27
+ export type Download = (file: FileAttachment) => void;
28
+ export type PreviewLink = (file: FileAttachment) => string | undefined;
29
+ export type FileManagement = {
30
+ upload: Upload;
31
+ download: Download;
32
+ previewLink: PreviewLink;
33
+ };
34
+ export declare const groupFiles: (doc: ManuscriptNode, files: FileAttachment[]) => ManuscriptFiles;
@@ -16,12 +16,10 @@
16
16
  import { TrackedAttrs } from '@manuscripts/track-changes-plugin';
17
17
  import { CitationNode, ManuscriptNode } from '@manuscripts/transform';
18
18
  import CiteProc from 'citeproc';
19
- import { Attrs } from 'prosemirror-model';
20
19
  import { Decoration } from 'prosemirror-view';
21
20
  import { PluginState } from './index';
22
21
  export declare const isBibliographyElement: (node: ManuscriptNode) => boolean;
23
22
  export type CitationNodes = [CitationNode, number][];
24
23
  export declare const buildDecorations: (state: PluginState, doc: ManuscriptNode) => Decoration[];
25
24
  export declare const getLatest: (a: TrackedAttrs, b: TrackedAttrs) => TrackedAttrs;
26
- export declare const getEffectiveAttrs: (node: ManuscriptNode, excludeDeletedNode?: boolean) => Attrs | undefined;
27
25
  export declare const buildCitations: (citations: CitationNodes) => CiteProc.Citation[];
@@ -13,8 +13,9 @@
13
13
  * See the License for the specific language governing permissions and
14
14
  * limitations under the License.
15
15
  */
16
- import { Capabilities, FileAttachment, FileManagement } from '@manuscripts/style-guide';
16
+ import { Capabilities } from '@manuscripts/style-guide';
17
17
  import { ManuscriptEditorView, ManuscriptNode } from '@manuscripts/transform';
18
+ import { FileAttachment, FileManagement } from '../lib/files';
18
19
  import { EditableBlockProps } from './editable_block';
19
20
  import { FigureView } from './figure';
20
21
  export interface FigureProps {
@@ -13,13 +13,12 @@
13
13
  * See the License for the specific language governing permissions and
14
14
  * limitations under the License.
15
15
  */
16
- import { Capabilities, FileAttachment, FileManagement } from '@manuscripts/style-guide';
16
+ import { FileAttachment, FileManagement } from '../lib/files';
17
17
  import BlockView from './block_view';
18
18
  import { EditableBlockProps } from './editable_block';
19
19
  interface FigureElementProps {
20
20
  fileManagement: FileManagement;
21
21
  getFiles: () => FileAttachment[];
22
- getCapabilities: () => Capabilities;
23
22
  }
24
23
  export declare class FigureElementView extends BlockView<EditableBlockProps & FigureElementProps> {
25
24
  private container;
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.13.24",
4
+ "version": "1.13.25",
5
5
  "repository": "github:Atypon-OpenSource/manuscripts-body-editor",
6
6
  "license": "Apache-2.0",
7
7
  "main": "dist/cjs",
@@ -30,7 +30,7 @@
30
30
  "@iarna/word-count": "^1.1.2",
31
31
  "@manuscripts/json-schema": "2.2.10",
32
32
  "@manuscripts/library": "1.3.10",
33
- "@manuscripts/style-guide": "1.13.15",
33
+ "@manuscripts/style-guide": "1.13.16",
34
34
  "@manuscripts/track-changes-plugin": "1.7.14",
35
35
  "@manuscripts/transform": "2.3.21",
36
36
  "@popperjs/core": "^2.11.8",
@@ -1,41 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.buildFileMap = void 0;
4
- const json_schema_1 = require("@manuscripts/json-schema");
5
- const track_changes_plugin_1 = require("@manuscripts/track-changes-plugin");
6
- const transform_1 = require("@manuscripts/transform");
7
- const bibliography_utils_1 = require("../plugins/bibliography/bibliography-utils");
8
- const buildFileMap = (doc) => {
9
- const figures = [];
10
- const supplements = [];
11
- const sections = [];
12
- const buildNode = (node, group) => {
13
- var _a;
14
- const attrs = (0, bibliography_utils_1.getEffectiveAttrs)(node, true);
15
- if (attrs) {
16
- const nodeChange = (_a = node.attrs.dataTracked) === null || _a === void 0 ? void 0 : _a.reduce(bibliography_utils_1.getLatest);
17
- if (nodeChange &&
18
- nodeChange.operation === track_changes_plugin_1.CHANGE_OPERATION.insert &&
19
- nodeChange.status === track_changes_plugin_1.CHANGE_STATUS.rejected) {
20
- return false;
21
- }
22
- group.push(node.type.create(Object.assign({}, attrs), node.content));
23
- }
24
- return false;
25
- };
26
- doc.descendants((node) => {
27
- if (node.type === transform_1.schema.nodes.section &&
28
- node.attrs.category === 'MPSectionCategory:abstract-graphical') {
29
- return buildNode(node, sections);
30
- }
31
- if (node.type === transform_1.schema.nodes.figure_element) {
32
- return buildNode(node, figures);
33
- }
34
- if (node.type === transform_1.schema.nodes.supplement) {
35
- buildNode(node, supplements);
36
- }
37
- });
38
- sections.push(transform_1.schema.nodes.section.create({ id: (0, transform_1.generateID)(json_schema_1.ObjectTypes.Section) }, figures), transform_1.schema.nodes.supplements.create({ id: (0, transform_1.generateID)(json_schema_1.ObjectTypes.Supplement) }, supplements));
39
- return (0, transform_1.encode)(transform_1.schema.nodes.manuscript.create({}, sections));
40
- };
41
- exports.buildFileMap = buildFileMap;
@@ -1,37 +0,0 @@
1
- import { ObjectTypes } from '@manuscripts/json-schema';
2
- import { CHANGE_OPERATION, CHANGE_STATUS, } from '@manuscripts/track-changes-plugin';
3
- import { encode, generateID, schema, } from '@manuscripts/transform';
4
- import { getEffectiveAttrs, getLatest, } from '../plugins/bibliography/bibliography-utils';
5
- export const buildFileMap = (doc) => {
6
- const figures = [];
7
- const supplements = [];
8
- const sections = [];
9
- const buildNode = (node, group) => {
10
- var _a;
11
- const attrs = getEffectiveAttrs(node, true);
12
- if (attrs) {
13
- const nodeChange = (_a = node.attrs.dataTracked) === null || _a === void 0 ? void 0 : _a.reduce(getLatest);
14
- if (nodeChange &&
15
- nodeChange.operation === CHANGE_OPERATION.insert &&
16
- nodeChange.status === CHANGE_STATUS.rejected) {
17
- return false;
18
- }
19
- group.push(node.type.create(Object.assign({}, attrs), node.content));
20
- }
21
- return false;
22
- };
23
- doc.descendants((node) => {
24
- if (node.type === schema.nodes.section &&
25
- node.attrs.category === 'MPSectionCategory:abstract-graphical') {
26
- return buildNode(node, sections);
27
- }
28
- if (node.type === schema.nodes.figure_element) {
29
- return buildNode(node, figures);
30
- }
31
- if (node.type === schema.nodes.supplement) {
32
- buildNode(node, supplements);
33
- }
34
- });
35
- sections.push(schema.nodes.section.create({ id: generateID(ObjectTypes.Section) }, figures), schema.nodes.supplements.create({ id: generateID(ObjectTypes.Supplement) }, supplements));
36
- return encode(schema.nodes.manuscript.create({}, sections));
37
- };
@@ -1,2 +0,0 @@
1
- import { ManuscriptNode } from '@manuscripts/transform';
2
- export declare const buildFileMap: (doc: ManuscriptNode) => Map<string, import("@manuscripts/json-schema").Model>;