@manuscripts/body-editor 3.8.0 → 3.8.2

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.
@@ -48,7 +48,7 @@ const placeholder_1 = __importDefault(require("../plugins/placeholder"));
48
48
  const prevent_empty_1 = __importDefault(require("../plugins/prevent-empty"));
49
49
  const search_replace_1 = __importDefault(require("../plugins/search-replace"));
50
50
  const section_title_1 = __importDefault(require("../plugins/section_title"));
51
- const section_category_1 = __importDefault(require("../plugins/section-category"));
51
+ const section_category_1 = __importDefault(require("../plugins/section_category"));
52
52
  const selected_suggestion_1 = __importDefault(require("../plugins/selected-suggestion"));
53
53
  const tables_cursor_fix_1 = __importDefault(require("../plugins/tables-cursor-fix"));
54
54
  const rules_1 = __importDefault(require("../rules"));
@@ -64,7 +64,8 @@ class PopperManager {
64
64
  this.destroy();
65
65
  }
66
66
  };
67
- if (contents.classList.contains('context-menu')) {
67
+ if (contents.classList.contains('context-menu') ||
68
+ contents.classList.contains('section-category')) {
68
69
  window.addEventListener('click', this.handleDocumentClick);
69
70
  }
70
71
  });
package/dist/cjs/menus.js CHANGED
@@ -200,8 +200,7 @@ const getEditorMenus = (editor) => {
200
200
  label: 'Author Notes',
201
201
  isEnabled: true,
202
202
  submenu: categories.map(insertBackmatterSectionMenu),
203
- isHidden: !(0, template_1.templateAllows)(state, transform_1.schema.nodes.author_notes) ||
204
- !categories.length,
203
+ isHidden: !categories.length,
205
204
  },
206
205
  {
207
206
  id: 'insert-section',
@@ -1,49 +1,64 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.buildPluginState = buildPluginState;
3
+ exports.sectionCategoryKey = void 0;
4
4
  const transform_1 = require("@manuscripts/transform");
5
+ const prosemirror_state_1 = require("prosemirror-state");
5
6
  const prosemirror_utils_1 = require("prosemirror-utils");
6
7
  const prosemirror_view_1 = require("prosemirror-view");
7
- const icons_1 = require("../../icons");
8
- const popper_1 = require("../../lib/popper");
9
- const popper = new popper_1.PopperManager();
10
- function createMenuItem(contents, handler, isDisabled = false, isSelected = false) {
8
+ const icons_1 = require("../icons");
9
+ exports.sectionCategoryKey = new prosemirror_state_1.PluginKey('section-category');
10
+ exports.default = (props) => new prosemirror_state_1.Plugin({
11
+ key: exports.sectionCategoryKey,
12
+ state: {
13
+ init: (_, state) => buildPluginState(state, props),
14
+ apply: (tr, value, oldState, newState) => {
15
+ if (!tr.docChanged) {
16
+ return value;
17
+ }
18
+ return buildPluginState(newState, props);
19
+ }
20
+ },
21
+ props: {
22
+ decorations: (state) => exports.sectionCategoryKey.getState(state)?.decorations || prosemirror_view_1.DecorationSet.empty,
23
+ },
24
+ });
25
+ const createMenuItem = (props, contents, handler, isDisabled, isSelected) => {
11
26
  const item = document.createElement('div');
12
- item.className = `menu-item ${isDisabled ? 'disabled' : ''} ${isSelected ? 'selected' : ''}`;
27
+ item.classList.add('menu-item');
28
+ if (isSelected) {
29
+ item.classList.add('selected');
30
+ }
31
+ if (isDisabled) {
32
+ item.classList.add('disabled');
33
+ }
13
34
  item.textContent = contents;
14
35
  item.addEventListener('mousedown', (event) => {
15
36
  handler(event);
16
- popper.destroy();
37
+ props.popper.destroy();
17
38
  });
18
39
  return item;
19
- }
20
- function createMenu(currentCategory, categories, usedCategoryIDs, onSelect) {
40
+ };
41
+ const createMenu = (props, currentCategory, categories, usedCategoryIDs, onSelect) => {
21
42
  const menu = document.createElement('div');
22
43
  menu.className = 'section-category menu';
23
44
  categories.forEach((category) => {
24
- const item = createMenuItem(category.titles[0], () => onSelect(category), category.isUnique && usedCategoryIDs.has(category.id), currentCategory === category);
45
+ const item = createMenuItem(props, category.titles[0], () => onSelect(category), category.isUnique && usedCategoryIDs.has(category.id), currentCategory === category);
25
46
  menu.appendChild(item);
26
47
  });
27
- document.addEventListener('mousedown', (event) => {
28
- if (!menu.contains(event.target)) {
29
- popper.destroy();
30
- }
31
- });
32
48
  return menu;
33
- }
34
- function createButton(view, pos, currentCategory, categories, usedCategoryIDs, canEdit = true, disabled) {
49
+ };
50
+ const createButton = (props, view, pos, currentCategory, categories, usedCategoryIDs, canEdit = true, disabled) => {
35
51
  const handleSelect = (category) => {
36
52
  const tr = view.state.tr;
37
53
  tr.setNodeAttribute(pos, 'category', category.id);
38
54
  view.dispatch(tr);
39
55
  };
40
- const arrow = document.createElement('div');
41
- arrow.className = 'section-category popper-arrow';
42
56
  const button = document.createElement('button');
43
57
  button.innerHTML = icons_1.sectionCategoryIcon;
44
58
  button.classList.add('section-category-button');
45
59
  button.setAttribute('aria-label', 'Section categories menu');
46
60
  if (currentCategory) {
61
+ button.setAttribute('data-tooltip-content', currentCategory.titles[0]);
47
62
  button.classList.add('assigned');
48
63
  }
49
64
  if (disabled) {
@@ -51,38 +66,18 @@ function createButton(view, pos, currentCategory, categories, usedCategoryIDs, c
51
66
  }
52
67
  else if (canEdit) {
53
68
  button.addEventListener('mousedown', () => {
54
- popper.destroy();
55
- const menu = createMenu(currentCategory, categories, usedCategoryIDs, handleSelect);
56
- popper.show(button, menu, 'bottom-end', false, [
57
- { name: 'offset', options: { offset: [0, -10] } },
58
- ]);
59
- });
60
- }
61
- else {
62
- button.addEventListener('mouseenter', () => {
63
- const tooltip = document.createElement('div');
64
- tooltip.className = 'section-category tooltip';
65
- tooltip.textContent = 'Category:';
66
- const span = document.createElement('span');
67
- span.textContent = currentCategory?.titles[0] || '';
68
- tooltip.appendChild(span);
69
- tooltip.appendChild(arrow);
70
- popper.show(button, tooltip, 'left', false, [
71
- { name: 'offset', options: { offset: [0, 10] } },
72
- { name: 'arrow', options: { element: arrow } },
73
- ]);
74
- });
75
- button.addEventListener('mouseleave', () => {
76
- popper.destroy();
69
+ const menu = createMenu(props, currentCategory, categories, usedCategoryIDs, handleSelect);
70
+ props.popper.show(button, menu, 'bottom-end', false);
77
71
  });
78
72
  }
79
73
  return button;
80
- }
81
- function buildPluginState(state, props) {
74
+ };
75
+ const buildPluginState = (state, props) => {
82
76
  const decorations = [];
83
77
  const can = props.getCapabilities();
84
78
  const categories = props.sectionCategories;
85
79
  const usedCategoryIDs = getUsedSectionCategoryIDs(state);
80
+ const canEdit = !!can?.editArticle;
86
81
  state.doc.descendants((node, pos) => {
87
82
  if (node.type === transform_1.schema.nodes.box_element) {
88
83
  return false;
@@ -93,17 +88,24 @@ function buildPluginState(state, props) {
93
88
  const $pos = state.doc.resolve(pos);
94
89
  const group = getGroup($pos);
95
90
  const groupCategories = (0, transform_1.getGroupCategories)(categories, group);
96
- decorations.push(prosemirror_view_1.Decoration.widget(pos + 1, (view) => createButton(view, pos, category, groupCategories, usedCategoryIDs, can?.editArticle, categories.size === 0)));
91
+ const numOptions = groupCategories.length;
92
+ const shouldShow = !!category || (canEdit && numOptions >= 2);
93
+ if (shouldShow) {
94
+ const isEditable = canEdit && numOptions >= 2;
95
+ decorations.push(prosemirror_view_1.Decoration.widget(pos + 1, (view) => createButton(props, view, pos, category, groupCategories, usedCategoryIDs, isEditable, categories.size === 0)));
96
+ }
97
97
  return false;
98
98
  }
99
99
  });
100
100
  return { decorations: prosemirror_view_1.DecorationSet.create(state.doc, decorations) };
101
- }
101
+ };
102
102
  const getUsedSectionCategoryIDs = (state) => {
103
103
  const sections = (0, prosemirror_utils_1.findChildrenByType)(state.doc, transform_1.schema.nodes.section);
104
104
  const used = new Set();
105
105
  sections.forEach(({ node }) => {
106
- node.attrs.category && used.add(node.attrs.category);
106
+ if (node.attrs.category) {
107
+ used.add(node.attrs.category);
108
+ }
107
109
  });
108
110
  return used;
109
111
  };
@@ -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.8.0';
4
+ exports.VERSION = '3.8.2';
5
5
  exports.MATHJAX_VERSION = '3.2.2';
@@ -43,7 +43,7 @@ import placeholder from '../plugins/placeholder';
43
43
  import prevent_empty from '../plugins/prevent-empty';
44
44
  import search_replace from '../plugins/search-replace';
45
45
  import section_title from '../plugins/section_title';
46
- import section_category from '../plugins/section-category';
46
+ import section_category from '../plugins/section_category';
47
47
  import selected_suggestion from '../plugins/selected-suggestion';
48
48
  import table_editing_fix from '../plugins/tables-cursor-fix';
49
49
  import rules from '../rules';
@@ -61,7 +61,8 @@ export class PopperManager {
61
61
  this.destroy();
62
62
  }
63
63
  };
64
- if (contents.classList.contains('context-menu')) {
64
+ if (contents.classList.contains('context-menu') ||
65
+ contents.classList.contains('section-category')) {
65
66
  window.addEventListener('click', this.handleDocumentClick);
66
67
  }
67
68
  });
package/dist/es/menus.js CHANGED
@@ -197,8 +197,7 @@ export const getEditorMenus = (editor) => {
197
197
  label: 'Author Notes',
198
198
  isEnabled: true,
199
199
  submenu: categories.map(insertBackmatterSectionMenu),
200
- isHidden: !templateAllows(state, schema.nodes.author_notes) ||
201
- !categories.length,
200
+ isHidden: !categories.length,
202
201
  },
203
202
  {
204
203
  id: 'insert-section',
@@ -1,46 +1,61 @@
1
1
  import { getGroupCategories, isSectionNode, schema, } from '@manuscripts/transform';
2
+ import { Plugin, PluginKey } from 'prosemirror-state';
2
3
  import { findChildrenByType, findParentNodeOfTypeClosestToPos, } from 'prosemirror-utils';
3
4
  import { Decoration, DecorationSet } from 'prosemirror-view';
4
- import { sectionCategoryIcon } from '../../icons';
5
- import { PopperManager } from '../../lib/popper';
6
- const popper = new PopperManager();
7
- function createMenuItem(contents, handler, isDisabled = false, isSelected = false) {
5
+ import { sectionCategoryIcon } from '../icons';
6
+ export const sectionCategoryKey = new PluginKey('section-category');
7
+ export default (props) => new Plugin({
8
+ key: sectionCategoryKey,
9
+ state: {
10
+ init: (_, state) => buildPluginState(state, props),
11
+ apply: (tr, value, oldState, newState) => {
12
+ if (!tr.docChanged) {
13
+ return value;
14
+ }
15
+ return buildPluginState(newState, props);
16
+ }
17
+ },
18
+ props: {
19
+ decorations: (state) => sectionCategoryKey.getState(state)?.decorations || DecorationSet.empty,
20
+ },
21
+ });
22
+ const createMenuItem = (props, contents, handler, isDisabled, isSelected) => {
8
23
  const item = document.createElement('div');
9
- item.className = `menu-item ${isDisabled ? 'disabled' : ''} ${isSelected ? 'selected' : ''}`;
24
+ item.classList.add('menu-item');
25
+ if (isSelected) {
26
+ item.classList.add('selected');
27
+ }
28
+ if (isDisabled) {
29
+ item.classList.add('disabled');
30
+ }
10
31
  item.textContent = contents;
11
32
  item.addEventListener('mousedown', (event) => {
12
33
  handler(event);
13
- popper.destroy();
34
+ props.popper.destroy();
14
35
  });
15
36
  return item;
16
- }
17
- function createMenu(currentCategory, categories, usedCategoryIDs, onSelect) {
37
+ };
38
+ const createMenu = (props, currentCategory, categories, usedCategoryIDs, onSelect) => {
18
39
  const menu = document.createElement('div');
19
40
  menu.className = 'section-category menu';
20
41
  categories.forEach((category) => {
21
- const item = createMenuItem(category.titles[0], () => onSelect(category), category.isUnique && usedCategoryIDs.has(category.id), currentCategory === category);
42
+ const item = createMenuItem(props, category.titles[0], () => onSelect(category), category.isUnique && usedCategoryIDs.has(category.id), currentCategory === category);
22
43
  menu.appendChild(item);
23
44
  });
24
- document.addEventListener('mousedown', (event) => {
25
- if (!menu.contains(event.target)) {
26
- popper.destroy();
27
- }
28
- });
29
45
  return menu;
30
- }
31
- function createButton(view, pos, currentCategory, categories, usedCategoryIDs, canEdit = true, disabled) {
46
+ };
47
+ const createButton = (props, view, pos, currentCategory, categories, usedCategoryIDs, canEdit = true, disabled) => {
32
48
  const handleSelect = (category) => {
33
49
  const tr = view.state.tr;
34
50
  tr.setNodeAttribute(pos, 'category', category.id);
35
51
  view.dispatch(tr);
36
52
  };
37
- const arrow = document.createElement('div');
38
- arrow.className = 'section-category popper-arrow';
39
53
  const button = document.createElement('button');
40
54
  button.innerHTML = sectionCategoryIcon;
41
55
  button.classList.add('section-category-button');
42
56
  button.setAttribute('aria-label', 'Section categories menu');
43
57
  if (currentCategory) {
58
+ button.setAttribute('data-tooltip-content', currentCategory.titles[0]);
44
59
  button.classList.add('assigned');
45
60
  }
46
61
  if (disabled) {
@@ -48,38 +63,18 @@ function createButton(view, pos, currentCategory, categories, usedCategoryIDs, c
48
63
  }
49
64
  else if (canEdit) {
50
65
  button.addEventListener('mousedown', () => {
51
- popper.destroy();
52
- const menu = createMenu(currentCategory, categories, usedCategoryIDs, handleSelect);
53
- popper.show(button, menu, 'bottom-end', false, [
54
- { name: 'offset', options: { offset: [0, -10] } },
55
- ]);
56
- });
57
- }
58
- else {
59
- button.addEventListener('mouseenter', () => {
60
- const tooltip = document.createElement('div');
61
- tooltip.className = 'section-category tooltip';
62
- tooltip.textContent = 'Category:';
63
- const span = document.createElement('span');
64
- span.textContent = currentCategory?.titles[0] || '';
65
- tooltip.appendChild(span);
66
- tooltip.appendChild(arrow);
67
- popper.show(button, tooltip, 'left', false, [
68
- { name: 'offset', options: { offset: [0, 10] } },
69
- { name: 'arrow', options: { element: arrow } },
70
- ]);
71
- });
72
- button.addEventListener('mouseleave', () => {
73
- popper.destroy();
66
+ const menu = createMenu(props, currentCategory, categories, usedCategoryIDs, handleSelect);
67
+ props.popper.show(button, menu, 'bottom-end', false);
74
68
  });
75
69
  }
76
70
  return button;
77
- }
78
- export function buildPluginState(state, props) {
71
+ };
72
+ const buildPluginState = (state, props) => {
79
73
  const decorations = [];
80
74
  const can = props.getCapabilities();
81
75
  const categories = props.sectionCategories;
82
76
  const usedCategoryIDs = getUsedSectionCategoryIDs(state);
77
+ const canEdit = !!can?.editArticle;
83
78
  state.doc.descendants((node, pos) => {
84
79
  if (node.type === schema.nodes.box_element) {
85
80
  return false;
@@ -90,17 +85,24 @@ export function buildPluginState(state, props) {
90
85
  const $pos = state.doc.resolve(pos);
91
86
  const group = getGroup($pos);
92
87
  const groupCategories = getGroupCategories(categories, group);
93
- decorations.push(Decoration.widget(pos + 1, (view) => createButton(view, pos, category, groupCategories, usedCategoryIDs, can?.editArticle, categories.size === 0)));
88
+ const numOptions = groupCategories.length;
89
+ const shouldShow = !!category || (canEdit && numOptions >= 2);
90
+ if (shouldShow) {
91
+ const isEditable = canEdit && numOptions >= 2;
92
+ decorations.push(Decoration.widget(pos + 1, (view) => createButton(props, view, pos, category, groupCategories, usedCategoryIDs, isEditable, categories.size === 0)));
93
+ }
94
94
  return false;
95
95
  }
96
96
  });
97
97
  return { decorations: DecorationSet.create(state.doc, decorations) };
98
- }
98
+ };
99
99
  const getUsedSectionCategoryIDs = (state) => {
100
100
  const sections = findChildrenByType(state.doc, schema.nodes.section);
101
101
  const used = new Set();
102
102
  sections.forEach(({ node }) => {
103
- node.attrs.category && used.add(node.attrs.category);
103
+ if (node.attrs.category) {
104
+ used.add(node.attrs.category);
105
+ }
104
106
  });
105
107
  return used;
106
108
  };
@@ -1,2 +1,2 @@
1
- export const VERSION = '3.8.0';
1
+ export const VERSION = '3.8.2';
2
2
  export const MATHJAX_VERSION = '3.2.2';
@@ -1,6 +1,6 @@
1
1
  import { Plugin, PluginKey } from 'prosemirror-state';
2
2
  import { DecorationSet } from 'prosemirror-view';
3
- import { EditorProps } from '../../configs/ManuscriptsEditor';
3
+ import { EditorProps } from '../configs/ManuscriptsEditor';
4
4
  export declare const sectionCategoryKey: PluginKey<PluginState>;
5
5
  export interface PluginState {
6
6
  decorations: DecorationSet;
@@ -1,2 +1,2 @@
1
- export declare const VERSION = "3.8.0";
1
+ export declare const VERSION = "3.8.2";
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.8.0",
4
+ "version": "3.8.2",
5
5
  "repository": "github:Atypon-OpenSource/manuscripts-body-editor",
6
6
  "license": "Apache-2.0",
7
7
  "main": "dist/cjs",
@@ -40,7 +40,7 @@
40
40
  "@manuscripts/json-schema": "2.2.12",
41
41
  "@manuscripts/style-guide": "3.4.0",
42
42
  "@manuscripts/track-changes-plugin": "2.2.3",
43
- "@manuscripts/transform": "4.3.14",
43
+ "@manuscripts/transform": "4.3.15",
44
44
  "@popperjs/core": "2.11.8",
45
45
  "citeproc": "2.4.63",
46
46
  "codemirror": "5.65.19",
@@ -1,17 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.sectionCategoryKey = void 0;
4
- const prosemirror_state_1 = require("prosemirror-state");
5
- const prosemirror_view_1 = require("prosemirror-view");
6
- const section_category_utils_1 = require("./section-category-utils");
7
- exports.sectionCategoryKey = new prosemirror_state_1.PluginKey('section-category');
8
- exports.default = (props) => new prosemirror_state_1.Plugin({
9
- key: exports.sectionCategoryKey,
10
- state: {
11
- init: (_, state) => (0, section_category_utils_1.buildPluginState)(state, props),
12
- apply: (tr, value, oldState, newState) => (0, section_category_utils_1.buildPluginState)(newState, props),
13
- },
14
- props: {
15
- decorations: (state) => exports.sectionCategoryKey.getState(state)?.decorations || prosemirror_view_1.DecorationSet.empty,
16
- },
17
- });
@@ -1,14 +0,0 @@
1
- import { Plugin, PluginKey } from 'prosemirror-state';
2
- import { DecorationSet } from 'prosemirror-view';
3
- import { buildPluginState } from './section-category-utils';
4
- export const sectionCategoryKey = new PluginKey('section-category');
5
- export default (props) => new Plugin({
6
- key: sectionCategoryKey,
7
- state: {
8
- init: (_, state) => buildPluginState(state, props),
9
- apply: (tr, value, oldState, newState) => buildPluginState(newState, props),
10
- },
11
- props: {
12
- decorations: (state) => sectionCategoryKey.getState(state)?.decorations || DecorationSet.empty,
13
- },
14
- });
@@ -1,4 +0,0 @@
1
- import { EditorState } from 'prosemirror-state';
2
- import { EditorProps } from '../../configs/ManuscriptsEditor';
3
- import { PluginState } from './index';
4
- export declare function buildPluginState(state: EditorState, props: EditorProps): PluginState;