@manuscripts/body-editor 3.17.0 → 3.17.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.
@@ -22,7 +22,7 @@ class PopperManager {
22
22
  constructor() {
23
23
  this.isActive = () => !!this.activePopper;
24
24
  }
25
- show(target, contents, placement = 'bottom', showArrow = true, modifiers = [], autoFocus = true, onDestroy = undefined) {
25
+ show(target, contents, placement = 'bottom', showArrow = true, modifiers = [], autoFocus = true, autoCloseOnOutsideClick = true, onDestroy = undefined) {
26
26
  this.destroy();
27
27
  this.triggerElement = target;
28
28
  this.destructionListener = onDestroy;
@@ -85,9 +85,10 @@ class PopperManager {
85
85
  this.destroy();
86
86
  }
87
87
  };
88
- if (contents.classList.contains('context-menu') ||
88
+ if ((contents.classList.contains('context-menu') ||
89
89
  contents.classList.contains('language') ||
90
- contents.classList.contains('section-category')) {
90
+ contents.classList.contains('section-category')) &&
91
+ autoCloseOnOutsideClick) {
91
92
  window.addEventListener('click', this.handleDocumentClick);
92
93
  }
93
94
  });
@@ -177,7 +177,7 @@ class HorizontalPositionMenu {
177
177
  p.props.popper.replaceContent(content);
178
178
  }
179
179
  else {
180
- p.props.popper.show(this.positionMenuWrapper, content, 'left', false, [], true, () => {
180
+ p.props.popper.show(this.positionMenuWrapper, content, 'left', false, [], true, true, () => {
181
181
  this.menuOpen = false;
182
182
  });
183
183
  this.menuOpen = true;
@@ -48,7 +48,7 @@ var __importStar = (this && this.__importStar) || (function () {
48
48
  };
49
49
  })();
50
50
  Object.defineProperty(exports, "__esModule", { value: true });
51
- exports.saveBibliographyItem = exports.insertBibliographyItems = exports.deleteNode = exports.updateNodeAttrs = exports.findChildrenAttrsByType = exports.findChildrenByType = exports.findChildByType = exports.findChildByID = void 0;
51
+ exports.isSelectionInsideNode = exports.saveBibliographyItem = exports.insertBibliographyItems = exports.deleteNode = exports.updateNodeAttrs = exports.findChildrenAttrsByType = exports.findChildrenByType = exports.findChildByType = exports.findChildByID = void 0;
52
52
  const transform_1 = require("@manuscripts/transform");
53
53
  const prosemirror_state_1 = require("prosemirror-state");
54
54
  const utils = __importStar(require("prosemirror-utils"));
@@ -144,3 +144,12 @@ const saveBibliographyItem = (view, attrs) => {
144
144
  (0, exports.insertBibliographyItems)(view, attrs);
145
145
  };
146
146
  exports.saveBibliographyItem = saveBibliographyItem;
147
+ const isSelectionInsideNode = (view, node, pos) => {
148
+ const { from, to, empty } = view.state.selection;
149
+ const end = pos + node.nodeSize;
150
+ if (empty) {
151
+ return from > pos && from < end;
152
+ }
153
+ return from >= pos && to <= end;
154
+ };
155
+ exports.isSelectionInsideNode = isSelectionInsideNode;
package/dist/cjs/menus.js CHANGED
@@ -333,41 +333,6 @@ const getEditorMenus = (editor) => {
333
333
  {
334
334
  role: 'separator',
335
335
  },
336
- {
337
- id: 'insert-citation',
338
- label: 'Citation',
339
- shortcut: {
340
- mac: 'Option+CommandOrControl+C',
341
- pc: 'CommandOrControl+Option+C',
342
- },
343
- isEnabled: (0, utils_1.isEditAllowed)(state) &&
344
- isCommandValid((0, commands_1.canInsert)(transform_1.schema.nodes.citation)),
345
- run: doCommand(commands_1.insertInlineCitation),
346
- isHidden: !(0, template_1.templateAllows)(state, transform_1.schema.nodes.citation),
347
- },
348
- {
349
- id: 'insert-cross-reference',
350
- label: 'Cross-reference',
351
- shortcut: {
352
- mac: 'Option+CommandOrControl+R',
353
- pc: 'CommandOrControl+Option+R',
354
- },
355
- isEnabled: (0, utils_1.isEditAllowed)(state) && isCommandValid(commands_1.canInsertCrossReference),
356
- run: doCommand(commands_1.insertCrossReference),
357
- isHidden: !(0, template_1.templateAllows)(state, transform_1.schema.nodes.cross_reference),
358
- },
359
- {
360
- id: 'insert-footnote',
361
- label: 'Footnote',
362
- shortcut: {
363
- mac: 'Option+CommandOrControl+F',
364
- pc: 'CommandOrControl+Option+F',
365
- },
366
- isEnabled: (0, utils_1.isEditAllowed)(state) &&
367
- isCommandValid((0, commands_1.canInsert)(transform_1.schema.nodes.inline_footnote)),
368
- run: doCommand(commands_1.insertInlineFootnote),
369
- isHidden: !(0, template_1.templateAllows)(state, transform_1.schema.nodes.inline_footnote),
370
- },
371
336
  {
372
337
  id: 'insert-special-character',
373
338
  label: 'Special Characters',
@@ -608,8 +573,7 @@ const getEditorMenus = (editor) => {
608
573
  mac: 'Option+CommandOrControl+R',
609
574
  pc: 'CommandOrControl+Option+R',
610
575
  },
611
- isEnabled: (0, utils_1.isEditAllowed)(state) &&
612
- isCommandValid((0, commands_1.canInsert)(transform_1.schema.nodes.cross_reference)),
576
+ isEnabled: (0, utils_1.isEditAllowed)(state) && isCommandValid(commands_1.canInsertCrossReference),
613
577
  run: doCommand(commands_1.insertCrossReference),
614
578
  isHidden: !(0, template_1.templateAllows)(state, transform_1.schema.nodes.cross_reference),
615
579
  },
@@ -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.0';
4
+ exports.VERSION = '3.17.2';
5
5
  exports.MATHJAX_VERSION = '3.2.2';
@@ -23,6 +23,7 @@ const style_guide_1 = require("@manuscripts/style-guide");
23
23
  const track_changes_plugin_1 = require("@manuscripts/track-changes-plugin");
24
24
  const transform_1 = require("@manuscripts/transform");
25
25
  const isEqual_1 = __importDefault(require("lodash/isEqual"));
26
+ const xor_1 = __importDefault(require("lodash/xor"));
26
27
  const prosemirror_state_1 = require("prosemirror-state");
27
28
  const prosemirror_utils_1 = require("prosemirror-utils");
28
29
  const DeleteFootnoteDialog_1 = require("../components/views/DeleteFootnoteDialog");
@@ -32,25 +33,31 @@ const base_node_view_1 = require("./base_node_view");
32
33
  const creators_1 = require("./creators");
33
34
  const ReactSubView_1 = __importDefault(require("./ReactSubView"));
34
35
  const navigation_utils_1 = require("../lib/navigation-utils");
36
+ const view_1 = require("../lib/view");
35
37
  class FootnoteView extends base_node_view_1.BaseNodeView {
36
38
  constructor() {
37
39
  super(...arguments);
40
+ this.isMenuShown = false;
41
+ this.previousActionsLabels = [];
38
42
  this.initialise = () => {
39
43
  this.dom = document.createElement('div');
40
44
  this.dom.classList.add('footnote');
41
45
  this.dom.tabIndex = 0;
42
46
  this.contentDOM = document.createElement('div');
43
47
  this.contentDOM.classList.add('footnote-text');
44
- this.dom.addEventListener('mousedown', (e) => this.handleClick(e, false));
45
- this.dom.addEventListener('keydown', (0, navigation_utils_1.handleEnterKey)((e) => this.handleClick(e, true)));
46
- this.updateContents();
47
- };
48
- this.handleClick = (event, fromKeyboard = false) => {
49
- const element = event.target;
50
- const item = element.closest('.footnote');
51
- if (item) {
52
- this.showContextMenu(item, fromKeyboard);
48
+ if (!this.view.editable) {
49
+ const actions = this.getContextMenuActions();
50
+ if (actions.length > 0) {
51
+ this.dom.addEventListener('mousedown', () => this.showContextMenu(actions, true));
52
+ }
53
53
  }
54
+ this.dom.addEventListener('keydown', (0, navigation_utils_1.handleEnterKey)(() => {
55
+ const actions = this.getContextMenuActions();
56
+ if (actions.length > 0) {
57
+ this.showContextMenu(actions, true);
58
+ }
59
+ }));
60
+ this.updateContents();
54
61
  };
55
62
  this.handleMarkerClick = (e) => {
56
63
  e?.preventDefault();
@@ -134,35 +141,53 @@ class FootnoteView extends base_node_view_1.BaseNodeView {
134
141
  this.dom.innerHTML = '';
135
142
  this.dom.appendChild(marker);
136
143
  this.contentDOM && this.dom.appendChild(this.contentDOM);
144
+ const selectionInsideNode = (0, view_1.isSelectionInsideNode)(this.view, this.node, this.getPos());
145
+ const actions = this.getContextMenuActions();
146
+ const hasActions = actions.length > 0;
147
+ const currentLabels = actions.map(({ label }) => label);
148
+ const changedLabels = (0, xor_1.default)(currentLabels, this.previousActionsLabels);
149
+ if (selectionInsideNode &&
150
+ hasActions &&
151
+ (!this.isMenuShown || changedLabels.length > 0)) {
152
+ this.showContextMenu(actions, false);
153
+ this.previousActionsLabels = actions.map(({ label }) => label);
154
+ }
155
+ else if ((!hasActions || !selectionInsideNode) && this.isMenuShown) {
156
+ this.props.popper.destroy();
157
+ this.isMenuShown = false;
158
+ this.previousActionsLabels = [];
159
+ }
137
160
  }
138
161
  getFootnoteState() {
139
162
  const id = this.node.attrs.id;
140
163
  const fn = (0, footnotes_1.getFootnotesElementState)(this.view.state, id);
141
164
  return { id, fn };
142
165
  }
143
- showContextMenu(element, autoFocus) {
166
+ showContextMenu(actions, autoFocus) {
167
+ this.isMenuShown = true;
144
168
  this.props.popper.destroy();
169
+ this.contextMenu = (0, ReactSubView_1.default)(this.props, style_guide_1.ContextMenu, { actions }, this.node, this.getPos, this.view, ['context-menu', 'footnote-context-menu']);
170
+ this.props.popper.show(this.dom, this.contextMenu, 'right-start', true, [], autoFocus, false);
171
+ }
172
+ getContextMenuActions() {
145
173
  const can = this.props.getCapabilities();
146
174
  const { id, fn } = this.getFootnoteState();
147
- const componentProps = {
148
- actions: [],
149
- };
175
+ const actions = [];
150
176
  if (!fn?.unusedFootnoteIDs.has(id)) {
151
- componentProps.actions.push({
152
- label: 'Go to footnote Refernce',
177
+ actions.push({
178
+ label: 'Go to footnote Reference',
153
179
  action: () => this.handleMarkerClick(),
154
180
  icon: 'Scroll',
155
181
  });
156
182
  }
157
183
  if (can.editArticle && !(0, track_changes_plugin_1.isDeleted)(this.node)) {
158
- componentProps.actions.push({
184
+ actions.push({
159
185
  label: 'Delete',
160
186
  action: () => this.handleDeleteClick(),
161
187
  icon: 'Delete',
162
188
  });
163
189
  }
164
- this.contextMenu = (0, ReactSubView_1.default)(this.props, style_guide_1.ContextMenu, componentProps, this.node, this.getPos, this.view, ['context-menu', 'footnote-context-menu']);
165
- this.props.popper.show(element, this.contextMenu, 'right-start', true, [], autoFocus);
190
+ return actions;
166
191
  }
167
192
  }
168
193
  exports.FootnoteView = FootnoteView;
@@ -27,27 +27,27 @@ const base_node_view_1 = require("./base_node_view");
27
27
  const creators_1 = require("./creators");
28
28
  const ReactSubView_1 = __importDefault(require("./ReactSubView"));
29
29
  const track_changes_plugin_1 = require("@manuscripts/track-changes-plugin");
30
+ const navigation_utils_1 = require("../lib/navigation-utils");
31
+ const view_1 = require("../lib/view");
30
32
  class GeneralTableFootnoteView extends base_node_view_1.BaseNodeView {
31
33
  constructor() {
32
34
  super(...arguments);
35
+ this.isMenuShown = false;
33
36
  this.initialise = () => {
34
37
  this.dom = document.createElement('div');
35
38
  this.dom.classList.add('footnote', 'general-table-footnote');
36
- this.dom.addEventListener('mousedown', this.handleClick);
39
+ this.dom.tabIndex = 0;
40
+ this.dom.addEventListener('keydown', (0, navigation_utils_1.handleEnterKey)(() => {
41
+ const can = this.props.getCapabilities();
42
+ const canShowMenu = can.editArticle && !(0, track_changes_plugin_1.isDeleted)(this.node);
43
+ if (canShowMenu) {
44
+ this.showContextMenu(true);
45
+ }
46
+ }));
37
47
  this.contentDOM = document.createElement('div');
38
48
  this.contentDOM.classList.add('footnote-text');
39
49
  this.updateContents();
40
50
  };
41
- this.handleClick = (e) => {
42
- const element = e.target;
43
- const can = this.props.getCapabilities();
44
- if (can.editArticle) {
45
- const item = element.closest('.general-table-footnote');
46
- if (item) {
47
- this.showContextMenu(item);
48
- }
49
- }
50
- };
51
51
  this.handleDeleteClick = () => {
52
52
  const componentProps = {
53
53
  header: 'Delete table general note',
@@ -80,21 +80,31 @@ class GeneralTableFootnoteView extends base_node_view_1.BaseNodeView {
80
80
  super.updateContents();
81
81
  this.dom.innerHTML = '';
82
82
  this.contentDOM && this.dom.appendChild(this.contentDOM);
83
+ const selectionInsideNode = (0, view_1.isSelectionInsideNode)(this.view, this.node, this.getPos());
84
+ const can = this.props.getCapabilities();
85
+ const canShowMenu = can.editArticle && !(0, track_changes_plugin_1.isDeleted)(this.node);
86
+ if (canShowMenu && selectionInsideNode && !this.isMenuShown) {
87
+ this.showContextMenu(false);
88
+ }
89
+ else if ((!canShowMenu || !selectionInsideNode) && this.isMenuShown) {
90
+ this.props.popper.destroy();
91
+ this.isMenuShown = false;
92
+ }
83
93
  }
84
- showContextMenu(element) {
94
+ showContextMenu(autoFocus = false) {
95
+ this.isMenuShown = true;
85
96
  this.props.popper.destroy();
86
97
  const componentProps = {
87
- actions: [],
98
+ actions: [
99
+ {
100
+ label: 'Delete',
101
+ action: () => this.handleDeleteClick(),
102
+ icon: 'Delete',
103
+ },
104
+ ],
88
105
  };
89
- if (!(0, track_changes_plugin_1.isDeleted)(this.node)) {
90
- componentProps.actions.push({
91
- label: 'Delete',
92
- action: () => this.handleDeleteClick(),
93
- icon: 'Delete',
94
- });
95
- }
96
106
  this.contextMenu = (0, ReactSubView_1.default)(this.props, style_guide_1.ContextMenu, componentProps, this.node, this.getPos, this.view, ['context-menu', 'footnote-context-menu']);
97
- this.props.popper.show(element, this.contextMenu, 'right-start');
107
+ this.props.popper.show(this.dom, this.contextMenu, 'right-start', false, [], autoFocus, false);
98
108
  }
99
109
  }
100
110
  exports.GeneralTableFootnoteView = GeneralTableFootnoteView;
@@ -19,7 +19,7 @@ export class PopperManager {
19
19
  constructor() {
20
20
  this.isActive = () => !!this.activePopper;
21
21
  }
22
- show(target, contents, placement = 'bottom', showArrow = true, modifiers = [], autoFocus = true, onDestroy = undefined) {
22
+ show(target, contents, placement = 'bottom', showArrow = true, modifiers = [], autoFocus = true, autoCloseOnOutsideClick = true, onDestroy = undefined) {
23
23
  this.destroy();
24
24
  this.triggerElement = target;
25
25
  this.destructionListener = onDestroy;
@@ -82,9 +82,10 @@ export class PopperManager {
82
82
  this.destroy();
83
83
  }
84
84
  };
85
- if (contents.classList.contains('context-menu') ||
85
+ if ((contents.classList.contains('context-menu') ||
86
86
  contents.classList.contains('language') ||
87
- contents.classList.contains('section-category')) {
87
+ contents.classList.contains('section-category')) &&
88
+ autoCloseOnOutsideClick) {
88
89
  window.addEventListener('click', this.handleDocumentClick);
89
90
  }
90
91
  });
@@ -174,7 +174,7 @@ export class HorizontalPositionMenu {
174
174
  p.props.popper.replaceContent(content);
175
175
  }
176
176
  else {
177
- p.props.popper.show(this.positionMenuWrapper, content, 'left', false, [], true, () => {
177
+ p.props.popper.show(this.positionMenuWrapper, content, 'left', false, [], true, true, () => {
178
178
  this.menuOpen = false;
179
179
  });
180
180
  this.menuOpen = true;
@@ -100,3 +100,11 @@ export const saveBibliographyItem = (view, attrs) => {
100
100
  }
101
101
  insertBibliographyItems(view, attrs);
102
102
  };
103
+ export const isSelectionInsideNode = (view, node, pos) => {
104
+ const { from, to, empty } = view.state.selection;
105
+ const end = pos + node.nodeSize;
106
+ if (empty) {
107
+ return from > pos && from < end;
108
+ }
109
+ return from >= pos && to <= end;
110
+ };
package/dist/es/menus.js CHANGED
@@ -330,41 +330,6 @@ export const getEditorMenus = (editor) => {
330
330
  {
331
331
  role: 'separator',
332
332
  },
333
- {
334
- id: 'insert-citation',
335
- label: 'Citation',
336
- shortcut: {
337
- mac: 'Option+CommandOrControl+C',
338
- pc: 'CommandOrControl+Option+C',
339
- },
340
- isEnabled: isEditAllowed(state) &&
341
- isCommandValid(canInsert(schema.nodes.citation)),
342
- run: doCommand(insertInlineCitation),
343
- isHidden: !templateAllows(state, schema.nodes.citation),
344
- },
345
- {
346
- id: 'insert-cross-reference',
347
- label: 'Cross-reference',
348
- shortcut: {
349
- mac: 'Option+CommandOrControl+R',
350
- pc: 'CommandOrControl+Option+R',
351
- },
352
- isEnabled: isEditAllowed(state) && isCommandValid(canInsertCrossReference),
353
- run: doCommand(insertCrossReference),
354
- isHidden: !templateAllows(state, schema.nodes.cross_reference),
355
- },
356
- {
357
- id: 'insert-footnote',
358
- label: 'Footnote',
359
- shortcut: {
360
- mac: 'Option+CommandOrControl+F',
361
- pc: 'CommandOrControl+Option+F',
362
- },
363
- isEnabled: isEditAllowed(state) &&
364
- isCommandValid(canInsert(schema.nodes.inline_footnote)),
365
- run: doCommand(insertInlineFootnote),
366
- isHidden: !templateAllows(state, schema.nodes.inline_footnote),
367
- },
368
333
  {
369
334
  id: 'insert-special-character',
370
335
  label: 'Special Characters',
@@ -605,8 +570,7 @@ export const getEditorMenus = (editor) => {
605
570
  mac: 'Option+CommandOrControl+R',
606
571
  pc: 'CommandOrControl+Option+R',
607
572
  },
608
- isEnabled: isEditAllowed(state) &&
609
- isCommandValid(canInsert(schema.nodes.cross_reference)),
573
+ isEnabled: isEditAllowed(state) && isCommandValid(canInsertCrossReference),
610
574
  run: doCommand(insertCrossReference),
611
575
  isHidden: !templateAllows(state, schema.nodes.cross_reference),
612
576
  },
@@ -1,2 +1,2 @@
1
- export const VERSION = '3.17.0';
1
+ export const VERSION = '3.17.2';
2
2
  export const MATHJAX_VERSION = '3.2.2';
@@ -17,6 +17,7 @@ import { ContextMenu } from '@manuscripts/style-guide';
17
17
  import { isDeleted, isPendingInsert } from '@manuscripts/track-changes-plugin';
18
18
  import { schema } from '@manuscripts/transform';
19
19
  import isEqual from 'lodash/isEqual';
20
+ import xor from 'lodash/xor';
20
21
  import { NodeSelection } from 'prosemirror-state';
21
22
  import { findParentNodeOfTypeClosestToPos } from 'prosemirror-utils';
22
23
  import { DeleteFootnoteDialog, } from '../components/views/DeleteFootnoteDialog';
@@ -26,25 +27,31 @@ import { BaseNodeView } from './base_node_view';
26
27
  import { createNodeView } from './creators';
27
28
  import ReactSubView from './ReactSubView';
28
29
  import { handleEnterKey } from '../lib/navigation-utils';
30
+ import { isSelectionInsideNode } from '../lib/view';
29
31
  export class FootnoteView extends BaseNodeView {
30
32
  constructor() {
31
33
  super(...arguments);
34
+ this.isMenuShown = false;
35
+ this.previousActionsLabels = [];
32
36
  this.initialise = () => {
33
37
  this.dom = document.createElement('div');
34
38
  this.dom.classList.add('footnote');
35
39
  this.dom.tabIndex = 0;
36
40
  this.contentDOM = document.createElement('div');
37
41
  this.contentDOM.classList.add('footnote-text');
38
- this.dom.addEventListener('mousedown', (e) => this.handleClick(e, false));
39
- this.dom.addEventListener('keydown', handleEnterKey((e) => this.handleClick(e, true)));
40
- this.updateContents();
41
- };
42
- this.handleClick = (event, fromKeyboard = false) => {
43
- const element = event.target;
44
- const item = element.closest('.footnote');
45
- if (item) {
46
- this.showContextMenu(item, fromKeyboard);
42
+ if (!this.view.editable) {
43
+ const actions = this.getContextMenuActions();
44
+ if (actions.length > 0) {
45
+ this.dom.addEventListener('mousedown', () => this.showContextMenu(actions, true));
46
+ }
47
47
  }
48
+ this.dom.addEventListener('keydown', handleEnterKey(() => {
49
+ const actions = this.getContextMenuActions();
50
+ if (actions.length > 0) {
51
+ this.showContextMenu(actions, true);
52
+ }
53
+ }));
54
+ this.updateContents();
48
55
  };
49
56
  this.handleMarkerClick = (e) => {
50
57
  e?.preventDefault();
@@ -128,35 +135,53 @@ export class FootnoteView extends BaseNodeView {
128
135
  this.dom.innerHTML = '';
129
136
  this.dom.appendChild(marker);
130
137
  this.contentDOM && this.dom.appendChild(this.contentDOM);
138
+ const selectionInsideNode = isSelectionInsideNode(this.view, this.node, this.getPos());
139
+ const actions = this.getContextMenuActions();
140
+ const hasActions = actions.length > 0;
141
+ const currentLabels = actions.map(({ label }) => label);
142
+ const changedLabels = xor(currentLabels, this.previousActionsLabels);
143
+ if (selectionInsideNode &&
144
+ hasActions &&
145
+ (!this.isMenuShown || changedLabels.length > 0)) {
146
+ this.showContextMenu(actions, false);
147
+ this.previousActionsLabels = actions.map(({ label }) => label);
148
+ }
149
+ else if ((!hasActions || !selectionInsideNode) && this.isMenuShown) {
150
+ this.props.popper.destroy();
151
+ this.isMenuShown = false;
152
+ this.previousActionsLabels = [];
153
+ }
131
154
  }
132
155
  getFootnoteState() {
133
156
  const id = this.node.attrs.id;
134
157
  const fn = getFootnotesElementState(this.view.state, id);
135
158
  return { id, fn };
136
159
  }
137
- showContextMenu(element, autoFocus) {
160
+ showContextMenu(actions, autoFocus) {
161
+ this.isMenuShown = true;
138
162
  this.props.popper.destroy();
163
+ this.contextMenu = ReactSubView(this.props, ContextMenu, { actions }, this.node, this.getPos, this.view, ['context-menu', 'footnote-context-menu']);
164
+ this.props.popper.show(this.dom, this.contextMenu, 'right-start', true, [], autoFocus, false);
165
+ }
166
+ getContextMenuActions() {
139
167
  const can = this.props.getCapabilities();
140
168
  const { id, fn } = this.getFootnoteState();
141
- const componentProps = {
142
- actions: [],
143
- };
169
+ const actions = [];
144
170
  if (!fn?.unusedFootnoteIDs.has(id)) {
145
- componentProps.actions.push({
146
- label: 'Go to footnote Refernce',
171
+ actions.push({
172
+ label: 'Go to footnote Reference',
147
173
  action: () => this.handleMarkerClick(),
148
174
  icon: 'Scroll',
149
175
  });
150
176
  }
151
177
  if (can.editArticle && !isDeleted(this.node)) {
152
- componentProps.actions.push({
178
+ actions.push({
153
179
  label: 'Delete',
154
180
  action: () => this.handleDeleteClick(),
155
181
  icon: 'Delete',
156
182
  });
157
183
  }
158
- this.contextMenu = ReactSubView(this.props, ContextMenu, componentProps, this.node, this.getPos, this.view, ['context-menu', 'footnote-context-menu']);
159
- this.props.popper.show(element, this.contextMenu, 'right-start', true, [], autoFocus);
184
+ return actions;
160
185
  }
161
186
  }
162
187
  const getEffectiveChildCount = (node) => {
@@ -21,27 +21,27 @@ import { BaseNodeView } from './base_node_view';
21
21
  import { createNodeView } from './creators';
22
22
  import ReactSubView from './ReactSubView';
23
23
  import { isDeleted, isPendingInsert } from '@manuscripts/track-changes-plugin';
24
+ import { handleEnterKey } from '../lib/navigation-utils';
25
+ import { isSelectionInsideNode } from '../lib/view';
24
26
  export class GeneralTableFootnoteView extends BaseNodeView {
25
27
  constructor() {
26
28
  super(...arguments);
29
+ this.isMenuShown = false;
27
30
  this.initialise = () => {
28
31
  this.dom = document.createElement('div');
29
32
  this.dom.classList.add('footnote', 'general-table-footnote');
30
- this.dom.addEventListener('mousedown', this.handleClick);
33
+ this.dom.tabIndex = 0;
34
+ this.dom.addEventListener('keydown', handleEnterKey(() => {
35
+ const can = this.props.getCapabilities();
36
+ const canShowMenu = can.editArticle && !isDeleted(this.node);
37
+ if (canShowMenu) {
38
+ this.showContextMenu(true);
39
+ }
40
+ }));
31
41
  this.contentDOM = document.createElement('div');
32
42
  this.contentDOM.classList.add('footnote-text');
33
43
  this.updateContents();
34
44
  };
35
- this.handleClick = (e) => {
36
- const element = e.target;
37
- const can = this.props.getCapabilities();
38
- if (can.editArticle) {
39
- const item = element.closest('.general-table-footnote');
40
- if (item) {
41
- this.showContextMenu(item);
42
- }
43
- }
44
- };
45
45
  this.handleDeleteClick = () => {
46
46
  const componentProps = {
47
47
  header: 'Delete table general note',
@@ -74,21 +74,31 @@ export class GeneralTableFootnoteView extends BaseNodeView {
74
74
  super.updateContents();
75
75
  this.dom.innerHTML = '';
76
76
  this.contentDOM && this.dom.appendChild(this.contentDOM);
77
+ const selectionInsideNode = isSelectionInsideNode(this.view, this.node, this.getPos());
78
+ const can = this.props.getCapabilities();
79
+ const canShowMenu = can.editArticle && !isDeleted(this.node);
80
+ if (canShowMenu && selectionInsideNode && !this.isMenuShown) {
81
+ this.showContextMenu(false);
82
+ }
83
+ else if ((!canShowMenu || !selectionInsideNode) && this.isMenuShown) {
84
+ this.props.popper.destroy();
85
+ this.isMenuShown = false;
86
+ }
77
87
  }
78
- showContextMenu(element) {
88
+ showContextMenu(autoFocus = false) {
89
+ this.isMenuShown = true;
79
90
  this.props.popper.destroy();
80
91
  const componentProps = {
81
- actions: [],
92
+ actions: [
93
+ {
94
+ label: 'Delete',
95
+ action: () => this.handleDeleteClick(),
96
+ icon: 'Delete',
97
+ },
98
+ ],
82
99
  };
83
- if (!isDeleted(this.node)) {
84
- componentProps.actions.push({
85
- label: 'Delete',
86
- action: () => this.handleDeleteClick(),
87
- icon: 'Delete',
88
- });
89
- }
90
100
  this.contextMenu = ReactSubView(this.props, ContextMenu, componentProps, this.node, this.getPos, this.view, ['context-menu', 'footnote-context-menu']);
91
- this.props.popper.show(element, this.contextMenu, 'right-start');
101
+ this.props.popper.show(this.dom, this.contextMenu, 'right-start', false, [], autoFocus, false);
92
102
  }
93
103
  }
94
104
  export default createNodeView(GeneralTableFootnoteView);
@@ -20,7 +20,7 @@ export declare class PopperManager {
20
20
  private triggerElement?;
21
21
  private container?;
22
22
  private destructionListener?;
23
- show(target: Element, contents: HTMLElement, placement?: Placement, showArrow?: boolean, modifiers?: Array<Partial<StrictModifiers>>, autoFocus?: boolean, onDestroy?: ((i: Instance) => void) | undefined): void;
23
+ show(target: Element, contents: HTMLElement, placement?: Placement, showArrow?: boolean, modifiers?: Array<Partial<StrictModifiers>>, autoFocus?: boolean, autoCloseOnOutsideClick?: boolean, onDestroy?: ((i: Instance) => void) | undefined): void;
24
24
  destroy(): void;
25
25
  getContainer(): HTMLElement | undefined;
26
26
  update(): void;
@@ -13,9 +13,10 @@
13
13
  * See the License for the specific language governing permissions and
14
14
  * limitations under the License.
15
15
  */
16
- import { BibliographyItemAttrs, ManuscriptEditorView, ManuscriptNodeType } from '@manuscripts/transform';
16
+ import { BibliographyItemAttrs, ManuscriptEditorView, ManuscriptNode, ManuscriptNodeType } from '@manuscripts/transform';
17
17
  import { Attrs } from 'prosemirror-model';
18
18
  import * as utils from 'prosemirror-utils';
19
+ import { EditorView } from 'prosemirror-view';
19
20
  export declare const findChildByID: (view: ManuscriptEditorView, id: string) => utils.NodeWithPos | undefined;
20
21
  export declare const findChildByType: (view: ManuscriptEditorView, type: ManuscriptNodeType) => utils.NodeWithPos | undefined;
21
22
  export declare const findChildrenByType: (view: ManuscriptEditorView, type: ManuscriptNodeType) => utils.NodeWithPos[];
@@ -24,3 +25,4 @@ export declare const updateNodeAttrs: (view: ManuscriptEditorView, type: Manuscr
24
25
  export declare const deleteNode: (view: ManuscriptEditorView, id: string) => void;
25
26
  export declare const insertBibliographyItems: (view: ManuscriptEditorView, items: BibliographyItemAttrs[]) => void;
26
27
  export declare const saveBibliographyItem: (view: ManuscriptEditorView, attrs: BibliographyItemAttrs[]) => void;
28
+ export declare const isSelectionInsideNode: (view: EditorView, node: ManuscriptNode, pos: number) => boolean;
@@ -1,2 +1,2 @@
1
- export declare const VERSION = "3.17.0";
1
+ export declare const VERSION = "3.17.2";
2
2
  export declare const MATHJAX_VERSION = "3.2.2";
@@ -13,6 +13,7 @@
13
13
  * See the License for the specific language governing permissions and
14
14
  * limitations under the License.
15
15
  */
16
+ import { ContextMenuProps } from '@manuscripts/style-guide';
16
17
  import { FootnoteNode } from '@manuscripts/transform';
17
18
  import { Transaction } from 'prosemirror-state';
18
19
  import { Trackable } from '../types';
@@ -20,14 +21,16 @@ import { BaseNodeView } from './base_node_view';
20
21
  export declare class FootnoteView extends BaseNodeView<Trackable<FootnoteNode>> {
21
22
  dialog: HTMLElement;
22
23
  contextMenu: HTMLDivElement;
24
+ isMenuShown: boolean;
25
+ previousActionsLabels: string[];
23
26
  initialise: () => void;
24
27
  updateContents(): void;
25
28
  getFootnoteState(): {
26
29
  id: string;
27
30
  fn: import("../plugins/footnotes").FootnotesElementState | undefined;
28
31
  };
29
- showContextMenu(element: HTMLElement, autoFocus: boolean): void;
30
- handleClick: (event: Event, fromKeyboard?: boolean) => void;
32
+ showContextMenu(actions: ContextMenuProps['actions'], autoFocus: boolean): void;
33
+ getContextMenuActions(): import("@manuscripts/style-guide").Actions[];
31
34
  handleMarkerClick: (e?: Event) => void;
32
35
  handleDeleteClick: (e?: Event) => void;
33
36
  handleDelete: () => void;
@@ -19,10 +19,10 @@ import { BaseNodeView } from './base_node_view';
19
19
  export declare class GeneralTableFootnoteView extends BaseNodeView<Trackable<GeneralTableFootnoteNode>> {
20
20
  dialog: HTMLElement;
21
21
  contextMenu: HTMLDivElement;
22
+ isMenuShown: boolean;
22
23
  initialise: () => void;
23
24
  updateContents(): void;
24
- handleClick: (e: Event) => void;
25
- showContextMenu(element: HTMLElement): void;
25
+ showContextMenu(autoFocus?: boolean): void;
26
26
  handleDeleteClick: () => void;
27
27
  handleDelete: () => void;
28
28
  }
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.0",
4
+ "version": "3.17.2",
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.1",
45
45
  "@manuscripts/track-changes-plugin": "2.4.0",
46
- "@manuscripts/transform": "4.5.1",
46
+ "@manuscripts/transform": "4.5.2",
47
47
  "@popperjs/core": "2.11.8",
48
48
  "citeproc": "2.4.63",
49
49
  "codemirror": "5.65.19",
package/src/lib/popper.ts CHANGED
@@ -36,6 +36,7 @@ export class PopperManager {
36
36
  showArrow = true,
37
37
  modifiers: Array<Partial<StrictModifiers>> = [],
38
38
  autoFocus = true,
39
+ autoCloseOnOutsideClick = true,
39
40
  onDestroy: ((i: Instance) => void) | undefined = undefined
40
41
  ) {
41
42
  // destroy any existing popper first
@@ -114,9 +115,10 @@ export class PopperManager {
114
115
  // add EventListener for checking if click was done outside of editor
115
116
  // only if popper has class 'context-menu'
116
117
  if (
117
- contents.classList.contains('context-menu') ||
118
- contents.classList.contains('language') ||
119
- contents.classList.contains('section-category')
118
+ (contents.classList.contains('context-menu') ||
119
+ contents.classList.contains('language') ||
120
+ contents.classList.contains('section-category')) &&
121
+ autoCloseOnOutsideClick
120
122
  ) {
121
123
  window.addEventListener('click', this.handleDocumentClick)
122
124
  }
@@ -261,6 +261,7 @@ export class HorizontalPositionMenu {
261
261
  false,
262
262
  [],
263
263
  true,
264
+ true,
264
265
  () => {
265
266
  this.menuOpen = false
266
267
  }
package/src/lib/view.ts CHANGED
@@ -27,6 +27,7 @@ import * as utils from 'prosemirror-utils'
27
27
 
28
28
  import { isHidden } from './track-changes-utils'
29
29
  import { sanitizeAttrsChange } from '@manuscripts/track-changes-plugin'
30
+ import { EditorView } from 'prosemirror-view'
30
31
 
31
32
  const metaNodeTypes = [
32
33
  schema.nodes.bibliography_item,
@@ -163,3 +164,19 @@ export const saveBibliographyItem = (
163
164
 
164
165
  insertBibliographyItems(view, attrs)
165
166
  }
167
+
168
+ export const isSelectionInsideNode = (
169
+ view: EditorView,
170
+ node: ManuscriptNode,
171
+ pos: number
172
+ ) => {
173
+ const { from, to, empty } = view.state.selection
174
+ const end = pos + node.nodeSize
175
+
176
+ // Treat a cursor as "inside" only when it is strictly within the node range.
177
+ if (empty) {
178
+ return from > pos && from < end
179
+ }
180
+
181
+ return from >= pos && to <= end
182
+ }
package/src/menus.tsx CHANGED
@@ -401,44 +401,6 @@ export const getEditorMenus = (
401
401
  {
402
402
  role: 'separator',
403
403
  },
404
- {
405
- id: 'insert-citation',
406
- label: 'Citation',
407
- shortcut: {
408
- mac: 'Option+CommandOrControl+C',
409
- pc: 'CommandOrControl+Option+C',
410
- },
411
- isEnabled:
412
- isEditAllowed(state) &&
413
- isCommandValid(canInsert(schema.nodes.citation)),
414
- run: doCommand(insertInlineCitation),
415
- isHidden: !templateAllows(state, schema.nodes.citation),
416
- },
417
- {
418
- id: 'insert-cross-reference',
419
- label: 'Cross-reference',
420
- shortcut: {
421
- mac: 'Option+CommandOrControl+R',
422
- pc: 'CommandOrControl+Option+R',
423
- },
424
- isEnabled:
425
- isEditAllowed(state) && isCommandValid(canInsertCrossReference),
426
- run: doCommand(insertCrossReference),
427
- isHidden: !templateAllows(state, schema.nodes.cross_reference),
428
- },
429
- {
430
- id: 'insert-footnote',
431
- label: 'Footnote',
432
- shortcut: {
433
- mac: 'Option+CommandOrControl+F',
434
- pc: 'CommandOrControl+Option+F',
435
- },
436
- isEnabled:
437
- isEditAllowed(state) &&
438
- isCommandValid(canInsert(schema.nodes.inline_footnote)),
439
- run: doCommand(insertInlineFootnote),
440
- isHidden: !templateAllows(state, schema.nodes.inline_footnote),
441
- },
442
404
  {
443
405
  id: 'insert-special-character',
444
406
  label: 'Special Characters',
@@ -698,8 +660,7 @@ export const getEditorMenus = (
698
660
  pc: 'CommandOrControl+Option+R',
699
661
  },
700
662
  isEnabled:
701
- isEditAllowed(state) &&
702
- isCommandValid(canInsert(schema.nodes.cross_reference)),
663
+ isEditAllowed(state) && isCommandValid(canInsertCrossReference),
703
664
  run: doCommand(insertCrossReference),
704
665
  isHidden: !templateAllows(state, schema.nodes.cross_reference),
705
666
  },
package/src/versions.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  //THIS FILE WAS GENERATED BY versions.mjs
2
- export const VERSION = '3.17.0';
2
+ export const VERSION = '3.17.2';
3
3
  export const MATHJAX_VERSION = '3.2.2';
@@ -19,6 +19,7 @@ import { isDeleted, isPendingInsert } from '@manuscripts/track-changes-plugin'
19
19
  import { FootnoteNode, ManuscriptNode, schema } from '@manuscripts/transform'
20
20
 
21
21
  import isEqual from 'lodash/isEqual'
22
+ import xor from 'lodash/xor'
22
23
  import { NodeSelection, Transaction } from 'prosemirror-state'
23
24
  import { findParentNodeOfTypeClosestToPos } from 'prosemirror-utils'
24
25
 
@@ -33,10 +34,13 @@ import { BaseNodeView } from './base_node_view'
33
34
  import { createNodeView } from './creators'
34
35
  import ReactSubView from './ReactSubView'
35
36
  import { handleEnterKey } from '../lib/navigation-utils'
37
+ import { isSelectionInsideNode } from '../lib/view'
36
38
 
37
39
  export class FootnoteView extends BaseNodeView<Trackable<FootnoteNode>> {
38
40
  dialog: HTMLElement
39
41
  contextMenu: HTMLDivElement
42
+ isMenuShown: boolean = false
43
+ previousActionsLabels: string[] = []
40
44
 
41
45
  public initialise = () => {
42
46
  this.dom = document.createElement('div')
@@ -44,10 +48,24 @@ export class FootnoteView extends BaseNodeView<Trackable<FootnoteNode>> {
44
48
  this.dom.tabIndex = 0
45
49
  this.contentDOM = document.createElement('div')
46
50
  this.contentDOM.classList.add('footnote-text')
47
- this.dom.addEventListener('mousedown', (e) => this.handleClick(e, false))
51
+ if (!this.view.editable) {
52
+ // when the editor is in the viewing mode we can't depend on the selection to show context-menu so we use mousedown
53
+ // as in that case will not have the same listener from prosemirror-view to interfere with it
54
+ const actions = this.getContextMenuActions()
55
+ if (actions.length > 0) {
56
+ this.dom.addEventListener('mousedown', () =>
57
+ this.showContextMenu(actions, true)
58
+ )
59
+ }
60
+ }
48
61
  this.dom.addEventListener(
49
62
  'keydown',
50
- handleEnterKey((e) => this.handleClick(e, true))
63
+ handleEnterKey(() => {
64
+ const actions = this.getContextMenuActions()
65
+ if (actions.length > 0) {
66
+ this.showContextMenu(actions, true)
67
+ }
68
+ })
51
69
  )
52
70
  this.updateContents()
53
71
  }
@@ -73,6 +91,29 @@ export class FootnoteView extends BaseNodeView<Trackable<FootnoteNode>> {
73
91
  this.dom.innerHTML = ''
74
92
  this.dom.appendChild(marker)
75
93
  this.contentDOM && this.dom.appendChild(this.contentDOM)
94
+
95
+ const selectionInsideNode = isSelectionInsideNode(
96
+ this.view,
97
+ this.node,
98
+ this.getPos()
99
+ )
100
+
101
+ const actions = this.getContextMenuActions()
102
+ const hasActions = actions.length > 0
103
+ const currentLabels = actions.map(({ label }) => label)
104
+ const changedLabels = xor(currentLabels, this.previousActionsLabels)
105
+ if (
106
+ selectionInsideNode &&
107
+ hasActions &&
108
+ (!this.isMenuShown || changedLabels.length > 0)
109
+ ) {
110
+ this.showContextMenu(actions, false)
111
+ this.previousActionsLabels = actions.map(({ label }) => label)
112
+ } else if ((!hasActions || !selectionInsideNode) && this.isMenuShown) {
113
+ this.props.popper.destroy()
114
+ this.isMenuShown = false
115
+ this.previousActionsLabels = []
116
+ }
76
117
  }
77
118
 
78
119
  getFootnoteState() {
@@ -81,55 +122,50 @@ export class FootnoteView extends BaseNodeView<Trackable<FootnoteNode>> {
81
122
  return { id, fn }
82
123
  }
83
124
 
84
- showContextMenu(element: HTMLElement, autoFocus: boolean) {
125
+ showContextMenu(actions: ContextMenuProps['actions'], autoFocus: boolean) {
126
+ this.isMenuShown = true
85
127
  this.props.popper.destroy()
86
-
87
- const can = this.props.getCapabilities()
88
- const { id, fn } = this.getFootnoteState()
89
-
90
- const componentProps: ContextMenuProps = {
91
- actions: [],
92
- }
93
- if (!fn?.unusedFootnoteIDs.has(id)) {
94
- componentProps.actions.push({
95
- label: 'Go to footnote Refernce',
96
- action: () => this.handleMarkerClick(),
97
- icon: 'Scroll',
98
- })
99
- }
100
- if (can.editArticle && !isDeleted(this.node)) {
101
- componentProps.actions.push({
102
- label: 'Delete',
103
- action: () => this.handleDeleteClick(),
104
- icon: 'Delete',
105
- })
106
- }
107
-
108
128
  this.contextMenu = ReactSubView(
109
129
  this.props,
110
130
  ContextMenu,
111
- componentProps,
131
+ { actions },
112
132
  this.node,
113
133
  this.getPos,
114
134
  this.view,
115
135
  ['context-menu', 'footnote-context-menu']
116
136
  )
117
137
  this.props.popper.show(
118
- element,
138
+ this.dom,
119
139
  this.contextMenu,
120
140
  'right-start',
121
141
  true,
122
142
  [],
123
- autoFocus
143
+ autoFocus,
144
+ false
124
145
  )
125
146
  }
126
147
 
127
- handleClick = (event: Event, fromKeyboard = false) => {
128
- const element = event.target as HTMLElement
129
- const item = element.closest('.footnote')
130
- if (item) {
131
- this.showContextMenu(item as HTMLElement, fromKeyboard)
148
+ getContextMenuActions() {
149
+ const can = this.props.getCapabilities()
150
+ const { id, fn } = this.getFootnoteState()
151
+ const actions: ContextMenuProps['actions'] = []
152
+
153
+ if (!fn?.unusedFootnoteIDs.has(id)) {
154
+ actions.push({
155
+ label: 'Go to footnote Reference',
156
+ action: () => this.handleMarkerClick(),
157
+ icon: 'Scroll',
158
+ })
159
+ }
160
+ if (can.editArticle && !isDeleted(this.node)) {
161
+ actions.push({
162
+ label: 'Delete',
163
+ action: () => this.handleDeleteClick(),
164
+ icon: 'Delete',
165
+ })
132
166
  }
167
+
168
+ return actions
133
169
  }
134
170
 
135
171
  handleMarkerClick = (e?: Event) => {
@@ -30,17 +30,30 @@ import { BaseNodeView } from './base_node_view'
30
30
  import { createNodeView } from './creators'
31
31
  import ReactSubView from './ReactSubView'
32
32
  import { isDeleted, isPendingInsert } from '@manuscripts/track-changes-plugin'
33
+ import { handleEnterKey } from '../lib/navigation-utils'
34
+ import { isSelectionInsideNode } from '../lib/view'
33
35
 
34
36
  export class GeneralTableFootnoteView extends BaseNodeView<
35
37
  Trackable<GeneralTableFootnoteNode>
36
38
  > {
37
39
  dialog: HTMLElement
38
40
  contextMenu: HTMLDivElement
41
+ isMenuShown: boolean = false
39
42
 
40
43
  public initialise = () => {
41
44
  this.dom = document.createElement('div')
42
45
  this.dom.classList.add('footnote', 'general-table-footnote')
43
- this.dom.addEventListener('mousedown', this.handleClick)
46
+ this.dom.tabIndex = 0
47
+ this.dom.addEventListener(
48
+ 'keydown',
49
+ handleEnterKey(() => {
50
+ const can = this.props.getCapabilities()
51
+ const canShowMenu = can.editArticle && !isDeleted(this.node)
52
+ if (canShowMenu) {
53
+ this.showContextMenu(true)
54
+ }
55
+ })
56
+ )
44
57
  this.contentDOM = document.createElement('div')
45
58
  this.contentDOM.classList.add('footnote-text')
46
59
  this.updateContents()
@@ -50,32 +63,34 @@ export class GeneralTableFootnoteView extends BaseNodeView<
50
63
  super.updateContents()
51
64
  this.dom.innerHTML = ''
52
65
  this.contentDOM && this.dom.appendChild(this.contentDOM)
53
- }
54
66
 
55
- handleClick = (e: Event) => {
56
- const element = e.target as HTMLElement
67
+ const selectionInsideNode = isSelectionInsideNode(
68
+ this.view,
69
+ this.node,
70
+ this.getPos()
71
+ )
57
72
  const can = this.props.getCapabilities()
58
-
59
- if (can.editArticle) {
60
- const item = element.closest('.general-table-footnote')
61
- if (item) {
62
- this.showContextMenu(item as HTMLElement)
63
- }
73
+ const canShowMenu = can.editArticle && !isDeleted(this.node)
74
+ if (canShowMenu && selectionInsideNode && !this.isMenuShown) {
75
+ this.showContextMenu(false)
76
+ } else if ((!canShowMenu || !selectionInsideNode) && this.isMenuShown) {
77
+ this.props.popper.destroy()
78
+ this.isMenuShown = false
64
79
  }
65
80
  }
66
81
 
67
- showContextMenu(element: HTMLElement) {
82
+ showContextMenu(autoFocus = false) {
83
+ this.isMenuShown = true
68
84
  this.props.popper.destroy()
69
85
 
70
86
  const componentProps: ContextMenuProps = {
71
- actions: [],
72
- }
73
- if (!isDeleted(this.node)) {
74
- componentProps.actions.push({
75
- label: 'Delete',
76
- action: () => this.handleDeleteClick(),
77
- icon: 'Delete',
78
- })
87
+ actions: [
88
+ {
89
+ label: 'Delete',
90
+ action: () => this.handleDeleteClick(),
91
+ icon: 'Delete',
92
+ },
93
+ ],
79
94
  }
80
95
 
81
96
  this.contextMenu = ReactSubView(
@@ -87,7 +102,15 @@ export class GeneralTableFootnoteView extends BaseNodeView<
87
102
  this.view,
88
103
  ['context-menu', 'footnote-context-menu']
89
104
  )
90
- this.props.popper.show(element, this.contextMenu, 'right-start')
105
+ this.props.popper.show(
106
+ this.dom,
107
+ this.contextMenu,
108
+ 'right-start',
109
+ false,
110
+ [],
111
+ autoFocus,
112
+ false
113
+ )
91
114
  }
92
115
 
93
116
  handleDeleteClick = () => {