@manuscripts/body-editor 3.17.3 → 3.17.5

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.
@@ -754,16 +754,14 @@ const insertAbstractSection = (category) => (state, dispatch, view) => {
754
754
  return false;
755
755
  }
756
756
  const abstracts = (0, doc_1.findAbstractsNode)(state.doc);
757
- const sections = (0, prosemirror_utils_1.findChildrenByType)(abstracts.node, transform_1.schema.nodes.section);
758
- if (sections.some((s) => s.node.attrs.category === category.id)) {
757
+ const abstractNodes = (0, prosemirror_utils_1.findChildrenByType)(abstracts.node, transform_1.schema.nodes.abstract);
758
+ if (abstractNodes.some((s) => s.node.attrs.category === category.id)) {
759
759
  return false;
760
760
  }
761
- const ga = (0, prosemirror_utils_1.findChildrenByType)(state.doc, transform_1.schema.nodes.graphical_abstract_section)[0];
762
- let pos = ga ? ga.pos : abstracts.pos + abstracts.node.content.size + 1;
763
- if (category.id === 'abstract') {
764
- pos = abstracts.pos + 1;
765
- }
766
- const node = transform_1.schema.nodes.section.create({ category: category.id }, [
761
+ const pos = (0, utils_1.findInsertionPosition)(transform_1.schema.nodes.abstract, abstracts.node) +
762
+ abstracts.pos +
763
+ 1;
764
+ const node = transform_1.schema.nodes.abstract.create({ category: category.id }, [
767
765
  transform_1.schema.nodes.section_title.create({}, transform_1.schema.text(category.titles[0])),
768
766
  transform_1.schema.nodes.paragraph.create({ placeholder: 'Type abstract here...' }),
769
767
  ]);
@@ -815,9 +813,9 @@ const insertGraphicalAbstract = (category) => (state, dispatch, view) => {
815
813
  if (sections.some((s) => s.node.attrs.category === category.id)) {
816
814
  return false;
817
815
  }
818
- const ga = (0, prosemirror_utils_1.findChildrenByType)(state.doc, transform_1.schema.nodes.graphical_abstract_section)[0];
819
- let pos = abstracts.pos + abstracts.node.content.size + 1;
820
- pos = ga && category.id === 'abstract-key-image' ? ga.pos : pos;
816
+ const pos = (0, utils_1.findInsertionPosition)(transform_1.schema.nodes.graphical_abstract_section, abstracts.node) +
817
+ abstracts.pos +
818
+ 1;
821
819
  const node = transform_1.schema.nodes.graphical_abstract_section.createAndFill({ category: category.id }, [
822
820
  transform_1.schema.nodes.section_title.create({}, transform_1.schema.text(category.titles[0])),
823
821
  createAndFillFigureElement(state),
@@ -1029,7 +1027,7 @@ const insertTOCSection = () => {
1029
1027
  return false;
1030
1028
  };
1031
1029
  exports.insertTOCSection = insertTOCSection;
1032
- const insertTransAbstract = (state, dispatch, category, insertAfterPos) => {
1030
+ const insertTransAbstract = (state, dispatch, category) => {
1033
1031
  if (!(0, template_1.templateAllows)(state, transform_1.schema.nodes.trans_abstract)) {
1034
1032
  return false;
1035
1033
  }
@@ -1044,9 +1042,7 @@ const insertTransAbstract = (state, dispatch, category, insertAfterPos) => {
1044
1042
  category,
1045
1043
  }, [title, paragraph]);
1046
1044
  const abstracts = (0, doc_1.findAbstractsNode)(state.doc);
1047
- const pos = insertAfterPos != null
1048
- ? insertAfterPos
1049
- : abstracts.pos + abstracts.node.nodeSize - 1;
1045
+ const pos = abstracts.node.content.size + abstracts.pos + 1;
1050
1046
  const tr = state.tr.insert(pos, node);
1051
1047
  const selection = prosemirror_state_1.TextSelection.create(tr.doc, pos + 1);
1052
1048
  tr.setSelection(selection).scrollIntoView();
@@ -1054,7 +1050,7 @@ const insertTransAbstract = (state, dispatch, category, insertAfterPos) => {
1054
1050
  return true;
1055
1051
  };
1056
1052
  exports.insertTransAbstract = insertTransAbstract;
1057
- const insertTransGraphicalAbstract = (category, insertAfterPos) => (state, dispatch, view) => {
1053
+ const insertTransGraphicalAbstract = (category) => (state, dispatch, view) => {
1058
1054
  if (!(0, template_1.templateAllows)(state, transform_1.schema.nodes.trans_graphical_abstract)) {
1059
1055
  return false;
1060
1056
  }
@@ -1063,9 +1059,7 @@ const insertTransGraphicalAbstract = (category, insertAfterPos) => (state, dispa
1063
1059
  }
1064
1060
  const lang = state.doc.attrs.primaryLanguageCode || 'en';
1065
1061
  const abstracts = (0, doc_1.findAbstractsNode)(state.doc);
1066
- const pos = insertAfterPos != null
1067
- ? insertAfterPos
1068
- : abstracts.pos + abstracts.node.content.size + 1;
1062
+ const pos = abstracts.node.content.size + abstracts.pos + 1;
1069
1063
  const node = transform_1.schema.nodes.trans_graphical_abstract.createAndFill({
1070
1064
  lang,
1071
1065
  category: category.id,
@@ -118,6 +118,7 @@ exports.default = (props, dispatch) => {
118
118
  headshot_element: (0, headshot_element_1.default)(props, dispatch),
119
119
  headshot_image: (0, headshot_image_editable_1.default)(props, dispatch),
120
120
  abstracts: (0, abstracts_1.default)(props),
121
+ abstract: (0, section_1.default)(props),
121
122
  trans_abstract: (0, translated_abstract_editable_1.default)(props),
122
123
  trans_graphical_abstract: (0, trans_graphical_abstract_editable_1.default)(props),
123
124
  attachment: (0, attachment_1.default)(props, dispatch),
@@ -263,7 +263,10 @@ class ContextMenu {
263
263
  menu.appendChild(this.createMenuSection((section) => {
264
264
  let nodeName = transform_1.nodeNames.get(type) || '';
265
265
  if (type === transform_1.schema.nodes.section_title) {
266
- nodeName = transform_1.nodeNames.get(transform_1.schema.nodes.section);
266
+ const containerType = $pos.parent.type;
267
+ nodeName =
268
+ transform_1.nodeNames.get(containerType) ??
269
+ transform_1.nodeNames.get(transform_1.schema.nodes.section);
267
270
  }
268
271
  section.appendChild(this.createMenuItem(`Delete ${nodeName}`, () => {
269
272
  this.deleteNode(type);
package/dist/cjs/menus.js CHANGED
@@ -489,7 +489,7 @@ const getEditorMenus = (editor) => {
489
489
  };
490
490
  const ABSTRACT_ID = 'abstract';
491
491
  const abstractSection = allAbstractsCategories.find((s) => s.id === ABSTRACT_ID);
492
- const ABSTRACT_GRAPHICAL_ID = 'abstract-graphical';
492
+ const ABSTRACT_GRAPHICAL_ID = 'graphical';
493
493
  const graphicalAbstractSection = allAbstractsCategories.find((s) => s.id === ABSTRACT_GRAPHICAL_ID);
494
494
  const abstractsSubmenuList = allAbstractsCategories.filter((c) => c.id !== ABSTRACT_ID && c.id !== ABSTRACT_GRAPHICAL_ID);
495
495
  const metadata = {
@@ -38,6 +38,7 @@ const icons = new Map([
38
38
  [nodes.paragraph, style_guide_1.OutlineParagraphIcon],
39
39
  [nodes.pullquote_element, style_guide_1.OutlinePullQuoteIcon],
40
40
  [nodes.section, style_guide_1.OutlineSectionIcon],
41
+ [nodes.abstract, style_guide_1.OutlineSectionIcon],
41
42
  [nodes.table_element, style_guide_1.OutlineTableIcon],
42
43
  [nodes.graphical_abstract_section, style_guide_1.OutlineSectionIcon],
43
44
  [nodes.trans_graphical_abstract, style_guide_1.OutlineSectionIcon],
@@ -82,7 +82,7 @@ const buildPluginState = (state, props) => {
82
82
  if (node.type === transform_1.schema.nodes.box_element) {
83
83
  return false;
84
84
  }
85
- if ((0, transform_1.isSectionNode)(node)) {
85
+ if ((0, transform_1.isSectionNode)(node) || (0, transform_1.isAbstractNode)(node)) {
86
86
  const categoryID = node.attrs.category;
87
87
  const category = categories.get(categoryID);
88
88
  const $pos = state.doc.resolve(pos);
@@ -100,7 +100,10 @@ const buildPluginState = (state, props) => {
100
100
  return { decorations: prosemirror_view_1.DecorationSet.create(state.doc, decorations) };
101
101
  };
102
102
  const getUsedSectionCategoryIDs = (state) => {
103
- const sections = (0, prosemirror_utils_1.findChildrenByType)(state.doc, transform_1.schema.nodes.section);
103
+ const sections = [
104
+ ...(0, prosemirror_utils_1.findChildrenByType)(state.doc, transform_1.schema.nodes.section),
105
+ ...(0, prosemirror_utils_1.findChildrenByType)(state.doc, transform_1.schema.nodes.abstract),
106
+ ];
104
107
  const used = new Set();
105
108
  sections.forEach(({ node }) => {
106
109
  if (node.attrs.category) {
@@ -21,8 +21,8 @@ const prosemirror_view_1 = require("prosemirror-view");
21
21
  const commands_1 = require("../commands");
22
22
  const icons_1 = require("../icons");
23
23
  const languages_1 = require("../lib/languages");
24
- const template_1 = require("../lib/template");
25
24
  const navigation_utils_1 = require("../lib/navigation-utils");
25
+ const template_1 = require("../lib/template");
26
26
  const createMenuItem = (props, contents, handler, isSelected = false, tabIndex) => {
27
27
  const item = document.createElement('div');
28
28
  item.className = `menu-item ${isSelected ? 'selected' : ''}`;
@@ -60,10 +60,6 @@ const createLanguageMenu = (props, selectedCode, onSelect) => {
60
60
  });
61
61
  return { menu, destroy };
62
62
  };
63
- const getInsertionPos = (doc, nodePos) => {
64
- const node = doc.nodeAt(nodePos);
65
- return node ? nodePos + node.nodeSize : null;
66
- };
67
63
  exports.default = (props) => new prosemirror_state_1.Plugin({
68
64
  props: {
69
65
  decorations: (state) => {
@@ -74,14 +70,11 @@ exports.default = (props) => new prosemirror_state_1.Plugin({
74
70
  const canEditTransGraphicalAbstract = can.editArticle &&
75
71
  (0, template_1.templateAllows)(state, transform_1.schema.nodes.trans_graphical_abstract);
76
72
  const widgets = [];
77
- state.doc.descendants((node, pos, parent) => {
78
- const isAbstractSection = (node.type === transform_1.schema.nodes.section ||
79
- node.type === transform_1.schema.nodes.graphical_abstract_section) &&
80
- parent?.type === transform_1.schema.nodes.abstracts;
73
+ state.doc.descendants((node, pos) => {
74
+ const isAbstractSection = (0, transform_1.isAbstractNode)(node) || (0, transform_1.isGraphicalAbstractSectionNode)(node);
81
75
  if (isAbstractSection) {
82
- const isGraphical = node.type === transform_1.schema.nodes.graphical_abstract_section;
83
76
  const category = props.sectionCategories.get(node.attrs.category);
84
- const canEdit = isGraphical
77
+ const canEdit = (0, transform_1.isGraphicalAbstractSectionNode)(node)
85
78
  ? canEditTransGraphicalAbstract &&
86
79
  category &&
87
80
  (0, commands_1.insertTransGraphicalAbstract)(category)(state)
@@ -96,15 +89,11 @@ exports.default = (props) => new prosemirror_state_1.Plugin({
96
89
  const handleActivate = (event) => {
97
90
  event.preventDefault();
98
91
  event.stopPropagation();
99
- const insertPos = getInsertionPos(view.state.doc, pos);
100
- if (insertPos == null) {
101
- return;
102
- }
103
- if (isGraphical && category) {
104
- (0, commands_1.insertTransGraphicalAbstract)(category, insertPos)(view.state, view.dispatch, view);
92
+ if ((0, transform_1.isGraphicalAbstractSectionNode)(node) && category) {
93
+ (0, commands_1.insertTransGraphicalAbstract)(category)(view.state, view.dispatch, view);
105
94
  }
106
95
  else {
107
- (0, commands_1.insertTransAbstract)(view.state, view.dispatch, node.attrs.category, insertPos);
96
+ (0, commands_1.insertTransAbstract)(view.state, view.dispatch, node.attrs.category);
108
97
  }
109
98
  };
110
99
  $span.addEventListener('mousedown', handleActivate);
@@ -113,8 +102,7 @@ exports.default = (props) => new prosemirror_state_1.Plugin({
113
102
  }, { key: `add-trans-${node.attrs.id}-${pos}` }));
114
103
  }
115
104
  }
116
- const isTransNode = node.type === transform_1.schema.nodes.trans_abstract ||
117
- node.type === transform_1.schema.nodes.trans_graphical_abstract;
105
+ const isTransNode = (0, transform_1.isTransAbstractNode)(node) || (0, transform_1.isTransGraphicalAbstractNode)(node);
118
106
  if (isTransNode) {
119
107
  const canEdit = node.type === transform_1.schema.nodes.trans_abstract
120
108
  ? canEditTransAbstract
@@ -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.17.3';
4
+ exports.VERSION = '3.17.5';
5
5
  exports.MATHJAX_VERSION = '3.2.2';
@@ -717,16 +717,14 @@ export const insertAbstractSection = (category) => (state, dispatch, view) => {
717
717
  return false;
718
718
  }
719
719
  const abstracts = findAbstractsNode(state.doc);
720
- const sections = findChildrenByType(abstracts.node, schema.nodes.section);
721
- if (sections.some((s) => s.node.attrs.category === category.id)) {
720
+ const abstractNodes = findChildrenByType(abstracts.node, schema.nodes.abstract);
721
+ if (abstractNodes.some((s) => s.node.attrs.category === category.id)) {
722
722
  return false;
723
723
  }
724
- const ga = findChildrenByType(state.doc, schema.nodes.graphical_abstract_section)[0];
725
- let pos = ga ? ga.pos : abstracts.pos + abstracts.node.content.size + 1;
726
- if (category.id === 'abstract') {
727
- pos = abstracts.pos + 1;
728
- }
729
- const node = schema.nodes.section.create({ category: category.id }, [
724
+ const pos = findInsertionPosition(schema.nodes.abstract, abstracts.node) +
725
+ abstracts.pos +
726
+ 1;
727
+ const node = schema.nodes.abstract.create({ category: category.id }, [
730
728
  schema.nodes.section_title.create({}, schema.text(category.titles[0])),
731
729
  schema.nodes.paragraph.create({ placeholder: 'Type abstract here...' }),
732
730
  ]);
@@ -776,9 +774,9 @@ export const insertGraphicalAbstract = (category) => (state, dispatch, view) =>
776
774
  if (sections.some((s) => s.node.attrs.category === category.id)) {
777
775
  return false;
778
776
  }
779
- const ga = findChildrenByType(state.doc, schema.nodes.graphical_abstract_section)[0];
780
- let pos = abstracts.pos + abstracts.node.content.size + 1;
781
- pos = ga && category.id === 'abstract-key-image' ? ga.pos : pos;
777
+ const pos = findInsertionPosition(schema.nodes.graphical_abstract_section, abstracts.node) +
778
+ abstracts.pos +
779
+ 1;
782
780
  const node = schema.nodes.graphical_abstract_section.createAndFill({ category: category.id }, [
783
781
  schema.nodes.section_title.create({}, schema.text(category.titles[0])),
784
782
  createAndFillFigureElement(state),
@@ -982,7 +980,7 @@ export const insertBibliographySection = () => {
982
980
  export const insertTOCSection = () => {
983
981
  return false;
984
982
  };
985
- export const insertTransAbstract = (state, dispatch, category, insertAfterPos) => {
983
+ export const insertTransAbstract = (state, dispatch, category) => {
986
984
  if (!templateAllows(state, schema.nodes.trans_abstract)) {
987
985
  return false;
988
986
  }
@@ -997,16 +995,14 @@ export const insertTransAbstract = (state, dispatch, category, insertAfterPos) =
997
995
  category,
998
996
  }, [title, paragraph]);
999
997
  const abstracts = findAbstractsNode(state.doc);
1000
- const pos = insertAfterPos != null
1001
- ? insertAfterPos
1002
- : abstracts.pos + abstracts.node.nodeSize - 1;
998
+ const pos = abstracts.node.content.size + abstracts.pos + 1;
1003
999
  const tr = state.tr.insert(pos, node);
1004
1000
  const selection = TextSelection.create(tr.doc, pos + 1);
1005
1001
  tr.setSelection(selection).scrollIntoView();
1006
1002
  dispatch(tr);
1007
1003
  return true;
1008
1004
  };
1009
- export const insertTransGraphicalAbstract = (category, insertAfterPos) => (state, dispatch, view) => {
1005
+ export const insertTransGraphicalAbstract = (category) => (state, dispatch, view) => {
1010
1006
  if (!templateAllows(state, schema.nodes.trans_graphical_abstract)) {
1011
1007
  return false;
1012
1008
  }
@@ -1015,9 +1011,7 @@ export const insertTransGraphicalAbstract = (category, insertAfterPos) => (state
1015
1011
  }
1016
1012
  const lang = state.doc.attrs.primaryLanguageCode || 'en';
1017
1013
  const abstracts = findAbstractsNode(state.doc);
1018
- const pos = insertAfterPos != null
1019
- ? insertAfterPos
1020
- : abstracts.pos + abstracts.node.content.size + 1;
1014
+ const pos = abstracts.node.content.size + abstracts.pos + 1;
1021
1015
  const node = schema.nodes.trans_graphical_abstract.createAndFill({
1022
1016
  lang,
1023
1017
  category: category.id,
@@ -113,6 +113,7 @@ export default (props, dispatch) => {
113
113
  headshot_element: headshotElement(props, dispatch),
114
114
  headshot_image: headshotImage(props, dispatch),
115
115
  abstracts: abstracts(props),
116
+ abstract: section(props),
116
117
  trans_abstract: transAbstract(props),
117
118
  trans_graphical_abstract: transGraphicalAbstract(props),
118
119
  attachment: attachment(props, dispatch),
@@ -259,7 +259,10 @@ export class ContextMenu {
259
259
  menu.appendChild(this.createMenuSection((section) => {
260
260
  let nodeName = nodeNames.get(type) || '';
261
261
  if (type === schema.nodes.section_title) {
262
- nodeName = nodeNames.get(schema.nodes.section);
262
+ const containerType = $pos.parent.type;
263
+ nodeName =
264
+ nodeNames.get(containerType) ??
265
+ nodeNames.get(schema.nodes.section);
263
266
  }
264
267
  section.appendChild(this.createMenuItem(`Delete ${nodeName}`, () => {
265
268
  this.deleteNode(type);
package/dist/es/menus.js CHANGED
@@ -486,7 +486,7 @@ export const getEditorMenus = (editor) => {
486
486
  };
487
487
  const ABSTRACT_ID = 'abstract';
488
488
  const abstractSection = allAbstractsCategories.find((s) => s.id === ABSTRACT_ID);
489
- const ABSTRACT_GRAPHICAL_ID = 'abstract-graphical';
489
+ const ABSTRACT_GRAPHICAL_ID = 'graphical';
490
490
  const graphicalAbstractSection = allAbstractsCategories.find((s) => s.id === ABSTRACT_GRAPHICAL_ID);
491
491
  const abstractsSubmenuList = allAbstractsCategories.filter((c) => c.id !== ABSTRACT_ID && c.id !== ABSTRACT_GRAPHICAL_ID);
492
492
  const metadata = {
@@ -32,6 +32,7 @@ const icons = new Map([
32
32
  [nodes.paragraph, OutlineParagraphIcon],
33
33
  [nodes.pullquote_element, OutlinePullQuoteIcon],
34
34
  [nodes.section, OutlineSectionIcon],
35
+ [nodes.abstract, OutlineSectionIcon],
35
36
  [nodes.table_element, OutlineTableIcon],
36
37
  [nodes.graphical_abstract_section, OutlineSectionIcon],
37
38
  [nodes.trans_graphical_abstract, OutlineSectionIcon],
@@ -1,4 +1,4 @@
1
- import { getGroupCategories, isSectionNode, schema, } from '@manuscripts/transform';
1
+ import { getGroupCategories, isAbstractNode, isSectionNode, schema, } from '@manuscripts/transform';
2
2
  import { Plugin, PluginKey } from 'prosemirror-state';
3
3
  import { findChildrenByType, findParentNodeOfTypeClosestToPos, } from 'prosemirror-utils';
4
4
  import { Decoration, DecorationSet } from 'prosemirror-view';
@@ -79,7 +79,7 @@ const buildPluginState = (state, props) => {
79
79
  if (node.type === schema.nodes.box_element) {
80
80
  return false;
81
81
  }
82
- if (isSectionNode(node)) {
82
+ if (isSectionNode(node) || isAbstractNode(node)) {
83
83
  const categoryID = node.attrs.category;
84
84
  const category = categories.get(categoryID);
85
85
  const $pos = state.doc.resolve(pos);
@@ -97,7 +97,10 @@ const buildPluginState = (state, props) => {
97
97
  return { decorations: DecorationSet.create(state.doc, decorations) };
98
98
  };
99
99
  const getUsedSectionCategoryIDs = (state) => {
100
- const sections = findChildrenByType(state.doc, schema.nodes.section);
100
+ const sections = [
101
+ ...findChildrenByType(state.doc, schema.nodes.section),
102
+ ...findChildrenByType(state.doc, schema.nodes.abstract),
103
+ ];
101
104
  const used = new Set();
102
105
  sections.forEach(({ node }) => {
103
106
  if (node.attrs.category) {
@@ -13,14 +13,14 @@
13
13
  * See the License for the specific language governing permissions and
14
14
  * limitations under the License.
15
15
  */
16
- import { schema } from '@manuscripts/transform';
16
+ import { isAbstractNode, isGraphicalAbstractSectionNode, isTransAbstractNode, isTransGraphicalAbstractNode, schema, } from '@manuscripts/transform';
17
17
  import { Plugin } from 'prosemirror-state';
18
18
  import { Decoration, DecorationSet } from 'prosemirror-view';
19
19
  import { insertTransAbstract, insertTransGraphicalAbstract } from '../commands';
20
20
  import { addAuthorIcon, translateIcon } from '../icons';
21
21
  import { getLanguage, getLanguageLabel } from '../lib/languages';
22
+ import { createKeyboardInteraction, handleEnterKey, } from '../lib/navigation-utils';
22
23
  import { templateAllows } from '../lib/template';
23
- import { handleEnterKey, createKeyboardInteraction, } from '../lib/navigation-utils';
24
24
  const createMenuItem = (props, contents, handler, isSelected = false, tabIndex) => {
25
25
  const item = document.createElement('div');
26
26
  item.className = `menu-item ${isSelected ? 'selected' : ''}`;
@@ -58,10 +58,6 @@ const createLanguageMenu = (props, selectedCode, onSelect) => {
58
58
  });
59
59
  return { menu, destroy };
60
60
  };
61
- const getInsertionPos = (doc, nodePos) => {
62
- const node = doc.nodeAt(nodePos);
63
- return node ? nodePos + node.nodeSize : null;
64
- };
65
61
  export default (props) => new Plugin({
66
62
  props: {
67
63
  decorations: (state) => {
@@ -72,14 +68,11 @@ export default (props) => new Plugin({
72
68
  const canEditTransGraphicalAbstract = can.editArticle &&
73
69
  templateAllows(state, schema.nodes.trans_graphical_abstract);
74
70
  const widgets = [];
75
- state.doc.descendants((node, pos, parent) => {
76
- const isAbstractSection = (node.type === schema.nodes.section ||
77
- node.type === schema.nodes.graphical_abstract_section) &&
78
- parent?.type === schema.nodes.abstracts;
71
+ state.doc.descendants((node, pos) => {
72
+ const isAbstractSection = isAbstractNode(node) || isGraphicalAbstractSectionNode(node);
79
73
  if (isAbstractSection) {
80
- const isGraphical = node.type === schema.nodes.graphical_abstract_section;
81
74
  const category = props.sectionCategories.get(node.attrs.category);
82
- const canEdit = isGraphical
75
+ const canEdit = isGraphicalAbstractSectionNode(node)
83
76
  ? canEditTransGraphicalAbstract &&
84
77
  category &&
85
78
  insertTransGraphicalAbstract(category)(state)
@@ -94,15 +87,11 @@ export default (props) => new Plugin({
94
87
  const handleActivate = (event) => {
95
88
  event.preventDefault();
96
89
  event.stopPropagation();
97
- const insertPos = getInsertionPos(view.state.doc, pos);
98
- if (insertPos == null) {
99
- return;
100
- }
101
- if (isGraphical && category) {
102
- insertTransGraphicalAbstract(category, insertPos)(view.state, view.dispatch, view);
90
+ if (isGraphicalAbstractSectionNode(node) && category) {
91
+ insertTransGraphicalAbstract(category)(view.state, view.dispatch, view);
103
92
  }
104
93
  else {
105
- insertTransAbstract(view.state, view.dispatch, node.attrs.category, insertPos);
94
+ insertTransAbstract(view.state, view.dispatch, node.attrs.category);
106
95
  }
107
96
  };
108
97
  $span.addEventListener('mousedown', handleActivate);
@@ -111,8 +100,7 @@ export default (props) => new Plugin({
111
100
  }, { key: `add-trans-${node.attrs.id}-${pos}` }));
112
101
  }
113
102
  }
114
- const isTransNode = node.type === schema.nodes.trans_abstract ||
115
- node.type === schema.nodes.trans_graphical_abstract;
103
+ const isTransNode = isTransAbstractNode(node) || isTransGraphicalAbstractNode(node);
116
104
  if (isTransNode) {
117
105
  const canEdit = node.type === schema.nodes.trans_abstract
118
106
  ? canEditTransAbstract
@@ -1,2 +1,2 @@
1
- export const VERSION = '3.17.3';
1
+ export const VERSION = '3.17.5';
2
2
  export const MATHJAX_VERSION = '3.2.2';
@@ -67,8 +67,8 @@ export declare const insertKeywords: (state: ManuscriptEditorState, dispatch?: D
67
67
  export declare const insertList: (type: ManuscriptNodeType, style?: string) => (state: ManuscriptEditorState, dispatch?: Dispatch, view?: EditorView) => boolean;
68
68
  export declare const insertBibliographySection: () => boolean;
69
69
  export declare const insertTOCSection: () => boolean;
70
- export declare const insertTransAbstract: (state: ManuscriptEditorState, dispatch?: Dispatch, category?: string, insertAfterPos?: number) => boolean;
71
- export declare const insertTransGraphicalAbstract: (category: SectionCategory, insertAfterPos?: number) => (state: ManuscriptEditorState, dispatch?: Dispatch, view?: EditorView) => boolean;
70
+ export declare const insertTransAbstract: (state: ManuscriptEditorState, dispatch?: Dispatch, category?: string) => boolean;
71
+ export declare const insertTransGraphicalAbstract: (category: SectionCategory) => (state: ManuscriptEditorState, dispatch?: Dispatch, view?: EditorView) => boolean;
72
72
  export declare const isAtStartOfTextBlock: (state: ManuscriptEditorState, $cursor: ResolvedPos, view?: ManuscriptEditorView) => boolean;
73
73
  export declare const isTextSelection: (selection: Selection) => selection is ManuscriptTextSelection;
74
74
  export declare const ignoreAtomBlockNodeBackward: (state: ManuscriptEditorState, dispatch?: Dispatch, view?: ManuscriptEditorView) => boolean;
@@ -1,2 +1,2 @@
1
- export declare const VERSION = "3.17.3";
1
+ export declare const VERSION = "3.17.5";
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.17.3",
4
+ "version": "3.17.5",
5
5
  "repository": "github:Atypon-OpenSource/manuscripts-body-editor",
6
6
  "license": "Apache-2.0",
7
7
  "main": "dist/cjs",
@@ -43,7 +43,7 @@
43
43
  "@iarna/word-count": "1.1.2",
44
44
  "@manuscripts/style-guide": "3.7.2",
45
45
  "@manuscripts/track-changes-plugin": "2.4.0",
46
- "@manuscripts/transform": "4.5.2",
46
+ "@manuscripts/transform": "4.5.4",
47
47
  "@popperjs/core": "2.11.8",
48
48
  "citeproc": "2.4.63",
49
49
  "codemirror": "5.65.19",
package/src/commands.ts CHANGED
@@ -1143,24 +1143,20 @@ export const insertAbstractSection =
1143
1143
  return false
1144
1144
  }
1145
1145
  const abstracts = findAbstractsNode(state.doc)
1146
- const sections = findChildrenByType(abstracts.node, schema.nodes.section)
1147
- // Check if the section already exists
1148
- if (sections.some((s) => s.node.attrs.category === category.id)) {
1146
+ const abstractNodes = findChildrenByType(
1147
+ abstracts.node,
1148
+ schema.nodes.abstract
1149
+ )
1150
+ if (abstractNodes.some((s) => s.node.attrs.category === category.id)) {
1149
1151
  return false
1150
1152
  }
1151
1153
 
1152
- // check if graphical abstract node exist to insert before it.
1153
- const ga = findChildrenByType(
1154
- state.doc,
1155
- schema.nodes.graphical_abstract_section
1156
- )[0]
1157
-
1158
- let pos = ga ? ga.pos : abstracts.pos + abstracts.node.content.size + 1
1159
- if (category.id === 'abstract') {
1160
- pos = abstracts.pos + 1
1161
- }
1154
+ const pos =
1155
+ findInsertionPosition(schema.nodes.abstract, abstracts.node) +
1156
+ abstracts.pos +
1157
+ 1
1162
1158
 
1163
- const node = schema.nodes.section.create({ category: category.id }, [
1159
+ const node = schema.nodes.abstract.create({ category: category.id }, [
1164
1160
  schema.nodes.section_title.create({}, schema.text(category.titles[0])),
1165
1161
  schema.nodes.paragraph.create({ placeholder: 'Type abstract here...' }),
1166
1162
  ])
@@ -1238,15 +1234,13 @@ export const insertGraphicalAbstract =
1238
1234
  return false
1239
1235
  }
1240
1236
 
1241
- const ga = findChildrenByType(
1242
- state.doc,
1243
- schema.nodes.graphical_abstract_section
1244
- )[0]
1245
-
1246
- // insert at the end of abstracts section
1247
- let pos = abstracts.pos + abstracts.node.content.size + 1
1248
- // abstract-key-image insert before abstract-graphical
1249
- pos = ga && category.id === 'abstract-key-image' ? ga.pos : pos
1237
+ const pos =
1238
+ findInsertionPosition(
1239
+ schema.nodes.graphical_abstract_section,
1240
+ abstracts.node
1241
+ ) +
1242
+ abstracts.pos +
1243
+ 1
1250
1244
 
1251
1245
  const node = schema.nodes.graphical_abstract_section.createAndFill(
1252
1246
  { category: category.id },
@@ -1537,8 +1531,7 @@ export const insertTOCSection = () => {
1537
1531
  export const insertTransAbstract = (
1538
1532
  state: ManuscriptEditorState,
1539
1533
  dispatch?: Dispatch,
1540
- category?: string,
1541
- insertAfterPos?: number
1534
+ category?: string
1542
1535
  ) => {
1543
1536
  if (!templateAllows(state, schema.nodes.trans_abstract)) {
1544
1537
  return false
@@ -1566,11 +1559,8 @@ export const insertTransAbstract = (
1566
1559
  )
1567
1560
 
1568
1561
  const abstracts = findAbstractsNode(state.doc)
1569
-
1570
- const pos =
1571
- insertAfterPos != null
1572
- ? insertAfterPos
1573
- : abstracts.pos + abstracts.node.nodeSize - 1
1562
+ // append at the end of the abstracts node, not just the first valid-but-earlier slot.
1563
+ const pos = abstracts.node.content.size + abstracts.pos + 1
1574
1564
  const tr = state.tr.insert(pos, node)
1575
1565
 
1576
1566
  const selection = TextSelection.create(tr.doc, pos + 1)
@@ -1581,7 +1571,7 @@ export const insertTransAbstract = (
1581
1571
  }
1582
1572
 
1583
1573
  export const insertTransGraphicalAbstract =
1584
- (category: SectionCategory, insertAfterPos?: number) =>
1574
+ (category: SectionCategory) =>
1585
1575
  (state: ManuscriptEditorState, dispatch?: Dispatch, view?: EditorView) => {
1586
1576
  if (!templateAllows(state, schema.nodes.trans_graphical_abstract)) {
1587
1577
  return false
@@ -1593,10 +1583,7 @@ export const insertTransGraphicalAbstract =
1593
1583
  const lang = state.doc.attrs.primaryLanguageCode || 'en'
1594
1584
 
1595
1585
  const abstracts = findAbstractsNode(state.doc)
1596
- const pos =
1597
- insertAfterPos != null
1598
- ? insertAfterPos
1599
- : abstracts.pos + abstracts.node.content.size + 1
1586
+ const pos = abstracts.node.content.size + abstracts.pos + 1
1600
1587
 
1601
1588
  const node = schema.nodes.trans_graphical_abstract.createAndFill(
1602
1589
  {
@@ -137,6 +137,7 @@ export default (
137
137
  headshot_element: headshotElement(props, dispatch),
138
138
  headshot_image: headshotImage(props, dispatch),
139
139
  abstracts: abstracts(props),
140
+ abstract: section(props),
140
141
  trans_abstract: transAbstract(props),
141
142
  trans_graphical_abstract: transGraphicalAbstract(props),
142
143
  attachment: attachment(props, dispatch),
@@ -397,7 +397,10 @@ export class ContextMenu {
397
397
  this.createMenuSection((section: HTMLElement) => {
398
398
  let nodeName = nodeNames.get(type) || ''
399
399
  if (type === schema.nodes.section_title) {
400
- nodeName = nodeNames.get(schema.nodes.section) as string
400
+ const containerType = $pos.parent.type
401
+ nodeName =
402
+ nodeNames.get(containerType) ??
403
+ (nodeNames.get(schema.nodes.section) as string)
401
404
  }
402
405
  section.appendChild(
403
406
  this.createMenuItem(`Delete ${nodeName}`, () => {
package/src/menus.tsx CHANGED
@@ -563,7 +563,7 @@ export const getEditorMenus = (
563
563
  const abstractSection = allAbstractsCategories.find(
564
564
  (s) => s.id === ABSTRACT_ID
565
565
  )
566
- const ABSTRACT_GRAPHICAL_ID = 'abstract-graphical'
566
+ const ABSTRACT_GRAPHICAL_ID = 'graphical'
567
567
  const graphicalAbstractSection = allAbstractsCategories.find(
568
568
  (s) => s.id === ABSTRACT_GRAPHICAL_ID
569
569
  )
@@ -69,6 +69,7 @@ const icons: Map<
69
69
  [nodes.paragraph, OutlineParagraphIcon],
70
70
  [nodes.pullquote_element, OutlinePullQuoteIcon],
71
71
  [nodes.section, OutlineSectionIcon],
72
+ [nodes.abstract, OutlineSectionIcon],
72
73
  [nodes.table_element, OutlineTableIcon],
73
74
  [nodes.graphical_abstract_section, OutlineSectionIcon],
74
75
  [nodes.trans_graphical_abstract, OutlineSectionIcon],
@@ -15,6 +15,7 @@
15
15
  */
16
16
  import {
17
17
  getGroupCategories,
18
+ isAbstractNode,
18
19
  isSectionNode,
19
20
  schema,
20
21
  SectionCategory,
@@ -154,7 +155,8 @@ const buildPluginState = (
154
155
  if (node.type === schema.nodes.box_element) {
155
156
  return false
156
157
  }
157
- if (isSectionNode(node)) {
158
+
159
+ if (isSectionNode(node) || isAbstractNode(node)) {
158
160
  const categoryID = node.attrs.category
159
161
  const category = categories.get(categoryID)
160
162
  const $pos = state.doc.resolve(pos)
@@ -191,7 +193,10 @@ const buildPluginState = (
191
193
  }
192
194
 
193
195
  const getUsedSectionCategoryIDs = (state: EditorState): Set<string> => {
194
- const sections = findChildrenByType(state.doc, schema.nodes.section)
196
+ const sections = [
197
+ ...findChildrenByType(state.doc, schema.nodes.section),
198
+ ...findChildrenByType(state.doc, schema.nodes.abstract),
199
+ ]
195
200
  const used = new Set<string>()
196
201
  sections.forEach(({ node }) => {
197
202
  if (node.attrs.category) {
@@ -14,8 +14,13 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
- import { schema } from '@manuscripts/transform'
18
- import { Node } from 'prosemirror-model'
17
+ import {
18
+ isAbstractNode,
19
+ isGraphicalAbstractSectionNode,
20
+ isTransAbstractNode,
21
+ isTransGraphicalAbstractNode,
22
+ schema,
23
+ } from '@manuscripts/transform'
19
24
  import { Plugin } from 'prosemirror-state'
20
25
  import { Decoration, DecorationSet } from 'prosemirror-view'
21
26
 
@@ -23,11 +28,11 @@ import { insertTransAbstract, insertTransGraphicalAbstract } from '../commands'
23
28
  import { EditorProps } from '../configs/ManuscriptsEditor'
24
29
  import { addAuthorIcon, translateIcon } from '../icons'
25
30
  import { getLanguage, getLanguageLabel } from '../lib/languages'
26
- import { templateAllows } from '../lib/template'
27
31
  import {
28
- handleEnterKey,
29
32
  createKeyboardInteraction,
33
+ handleEnterKey,
30
34
  } from '../lib/navigation-utils'
35
+ import { templateAllows } from '../lib/template'
31
36
 
32
37
  const createMenuItem = (
33
38
  props: EditorProps,
@@ -90,11 +95,6 @@ const createLanguageMenu = (
90
95
  return { menu, destroy }
91
96
  }
92
97
 
93
- const getInsertionPos = (doc: Node, nodePos: number): number | null => {
94
- const node = doc.nodeAt(nodePos)
95
- return node ? nodePos + node.nodeSize : null
96
- }
97
-
98
98
  export default (props: EditorProps) =>
99
99
  new Plugin<null>({
100
100
  props: {
@@ -110,19 +110,14 @@ export default (props: EditorProps) =>
110
110
 
111
111
  const widgets: Decoration[] = []
112
112
 
113
- state.doc.descendants((node, pos, parent) => {
113
+ state.doc.descendants((node, pos) => {
114
114
  const isAbstractSection =
115
- (node.type === schema.nodes.section ||
116
- node.type === schema.nodes.graphical_abstract_section) &&
117
- parent?.type === schema.nodes.abstracts
115
+ isAbstractNode(node) || isGraphicalAbstractSectionNode(node)
118
116
 
119
117
  // Show "Add translation" for abstract sections
120
118
  if (isAbstractSection) {
121
- const isGraphical =
122
- node.type === schema.nodes.graphical_abstract_section
123
119
  const category = props.sectionCategories.get(node.attrs.category)
124
-
125
- const canEdit = isGraphical
120
+ const canEdit = isGraphicalAbstractSectionNode(node)
126
121
  ? canEditTransGraphicalAbstract &&
127
122
  category &&
128
123
  insertTransGraphicalAbstract(category)(state)
@@ -142,12 +137,8 @@ export default (props: EditorProps) =>
142
137
  const handleActivate = (event: Event) => {
143
138
  event.preventDefault()
144
139
  event.stopPropagation()
145
- const insertPos = getInsertionPos(view.state.doc, pos)
146
- if (insertPos == null) {
147
- return
148
- }
149
- if (isGraphical && category) {
150
- insertTransGraphicalAbstract(category, insertPos)(
140
+ if (isGraphicalAbstractSectionNode(node) && category) {
141
+ insertTransGraphicalAbstract(category)(
151
142
  view.state,
152
143
  view.dispatch,
153
144
  view
@@ -156,8 +147,7 @@ export default (props: EditorProps) =>
156
147
  insertTransAbstract(
157
148
  view.state,
158
149
  view.dispatch,
159
- node.attrs.category,
160
- insertPos
150
+ node.attrs.category
161
151
  )
162
152
  }
163
153
  }
@@ -177,8 +167,7 @@ export default (props: EditorProps) =>
177
167
 
178
168
  // Language selector for trans_abstract and trans_graphical_abstract nodes
179
169
  const isTransNode =
180
- node.type === schema.nodes.trans_abstract ||
181
- node.type === schema.nodes.trans_graphical_abstract
170
+ isTransAbstractNode(node) || isTransGraphicalAbstractNode(node)
182
171
 
183
172
  if (isTransNode) {
184
173
  const canEdit =
package/src/versions.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  //THIS FILE WAS GENERATED BY versions.mjs
2
- export const VERSION = '3.17.3';
2
+ export const VERSION = '3.17.5';
3
3
  export const MATHJAX_VERSION = '3.2.2';
package/styles/Editor.css CHANGED
@@ -694,12 +694,14 @@
694
694
  grid-template-columns: 52px auto 100px 28px;
695
695
  }
696
696
  .ProseMirror .block-container.block-section,
697
+ .ProseMirror .block-container.block-abstract,
697
698
  .ProseMirror .block-container.block-graphical_abstract_section {
698
699
  position: relative;
699
700
  display: grid;
700
701
  grid-template-columns: auto;
701
702
  }
702
703
  .ProseMirror .block-container.block-section section,
704
+ .ProseMirror .block-container.block-abstract section,
703
705
  .ProseMirror .block-container.block-graphical_abstract_section section {
704
706
  position: relative;
705
707
  }
@@ -707,6 +709,7 @@
707
709
  .ProseMirror
708
710
  .block-container:not(
709
711
  .block-section,
712
+ .block-abstract,
710
713
  .block-graphical_abstract_section
711
714
  ):hover {
712
715
  z-index: 2;
@@ -789,6 +792,7 @@
789
792
  .block-container:not(
790
793
  .block-section,
791
794
  .block-box_element,
795
+ .block-abstract,
792
796
  .block-graphical_abstract_section
793
797
  ):hover
794
798
  .block-gutter,
@@ -796,6 +800,7 @@
796
800
  .block-container:not(
797
801
  .block-section,
798
802
  .block-box_element,
803
+ .block-abstract,
799
804
  .block-graphical_abstract_section
800
805
  ):focus-within
801
806
  .block-gutter {
@@ -818,6 +823,7 @@
818
823
  .block-container:not(
819
824
  .block-section,
820
825
  .block-box_element,
826
+ .block-abstract,
821
827
  .block-graphical_abstract_section
822
828
  ):hover
823
829
  .action-gutter,
@@ -825,6 +831,7 @@
825
831
  .block-container:not(
826
832
  .block-section,
827
833
  .block-box_element,
834
+ .block-abstract,
828
835
  .block-graphical_abstract_section
829
836
  ):focus-within
830
837
  .action-gutter {