@manuscripts/body-editor 1.7.8-LEAN-3160-2 → 1.7.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -15,7 +15,7 @@
15
15
  * limitations under the License.
16
16
  */
17
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
- exports.editAttrsTrackingIcon = exports.commentIcon = exports.editIcon = void 0;
18
+ exports.alertIcon = exports.editAttrsTrackingIcon = exports.commentIcon = exports.editIcon = void 0;
19
19
  exports.editIcon = `
20
20
  <svg
21
21
  width="14"
@@ -102,3 +102,19 @@ exports.editAttrsTrackingIcon = `
102
102
  />
103
103
  </svg>
104
104
  `;
105
+ exports.alertIcon = `
106
+ <svg
107
+ width="12"
108
+ height="12"
109
+ viewBox="0 0 12 12"
110
+ fill="none"
111
+ xmlns="http://www.w3.org/2000/svg"
112
+ >
113
+ <path
114
+ fill-rule="evenodd"
115
+ clip-rule="evenodd"
116
+ d="M6 12C2.68629 12 1.18852e-06 9.31371 1.47821e-06 6C1.7679e-06 2.68629 2.68629 1.39444e-07 6 4.29138e-07C9.31371 7.18831e-07 12 2.68629 12 6C12 9.31371 9.31371 12 6 12ZM6.74998 2.99996L6.75 6.37462C6.75 6.78819 6.41522 7.12243 6.00166 7.12334C5.58681 7.12426 5.25001 6.78821 5.25001 6.37335L5.25 3.00082C5.25 2.58629 5.58629 2.25037 6.00082 2.25083C6.4147 2.25128 6.74998 2.58607 6.74998 2.99996ZM6.75 8.99263C6.75 9.46884 6.47288 9.75 5.99853 9.75C5.52419 9.75 5.25 9.47179 5.25 8.99558C5.25 8.51937 5.52421 8.25 5.99855 8.25C6.47289 8.25 6.75 8.51642 6.75 8.99263Z"
117
+ fill="#FE8F1F"
118
+ />
119
+ </svg>
120
+ `;
@@ -696,37 +696,28 @@ const insertTableFootnote = (node, position, state, dispatch) => {
696
696
  });
697
697
  const insertedAt = state.selection.to;
698
698
  const inlineFootnotes = (0, prosemirror_utils_1.findChildrenByType)(node, transform_1.schema.nodes.inline_footnote);
699
- const labels = inlineFootnotes.map((nodeWithPos) => nodeWithPos.node.attrs.contents);
700
699
  const inlineFootnoteNode = state.schema.nodes.inline_footnote.create({
701
700
  rids: [footnote.attrs.id],
702
- contents: labels.length ? Math.max(...labels) + 1 : 1,
701
+ contents: inlineFootnotes.length + 1,
703
702
  });
704
703
  const tr = state.tr;
705
704
  tr.insert(insertedAt, inlineFootnoteNode);
705
+ const footnoteElement = state.schema.nodes.footnotes_element.create({}, footnote);
706
+ const tableElementFooter = (0, prosemirror_utils_1.findChildrenByType)(node, transform_1.schema.nodes.table_element_footer);
706
707
  let insertionPos;
707
- const footnotesElement = (0, prosemirror_utils_1.findChildrenByType)(node, transform_1.schema.nodes.footnotes_element);
708
- if (footnotesElement.length) {
709
- const pos = footnotesElement[0].pos;
710
- insertionPos = position + pos + footnotesElement[0].node.nodeSize + 1;
711
- tr.insert(insertionPos, footnote);
708
+ if (tableElementFooter.length) {
709
+ const pos = tableElementFooter[0].pos;
710
+ insertionPos = position + pos + tableElementFooter[0].node.nodeSize + 1;
711
+ tr.insert(insertionPos, footnoteElement);
712
712
  }
713
713
  else {
714
- const footnoteElement = state.schema.nodes.footnotes_element.create({}, footnote);
715
- const tableElementFooter = (0, prosemirror_utils_1.findChildrenByType)(node, transform_1.schema.nodes.table_element_footer);
716
- if (tableElementFooter.length) {
717
- const pos = tableElementFooter[0].pos;
718
- insertionPos = position + pos + tableElementFooter[0].node.nodeSize + 1;
719
- tr.insert(insertionPos, footnoteElement);
720
- }
721
- else {
722
- const tableSize = (_a = node.content.firstChild) === null || _a === void 0 ? void 0 : _a.nodeSize;
723
- if (tableSize) {
724
- insertionPos = position + tableSize + 2;
725
- const tableElementFooter = transform_1.schema.nodes.table_element_footer.create({
726
- id: (0, transform_1.generateID)(json_schema_1.ObjectTypes.TableElementFooter),
727
- }, [footnoteElement]);
728
- tr.insert(insertionPos, tableElementFooter);
729
- }
714
+ const tableSize = (_a = node.content.firstChild) === null || _a === void 0 ? void 0 : _a.nodeSize;
715
+ if (tableSize) {
716
+ insertionPos = position + tableSize + 2;
717
+ const tableElementFooter = transform_1.schema.nodes.table_element_footer.create({
718
+ id: (0, transform_1.generateID)(json_schema_1.ObjectTypes.TableElementFooter),
719
+ }, [footnoteElement]);
720
+ tr.insert(insertionPos, tableElementFooter);
730
721
  }
731
722
  }
732
723
  if (dispatch && insertionPos) {
@@ -14,16 +14,11 @@
14
14
  * See the License for the specific language governing permissions and
15
15
  * limitations under the License.
16
16
  */
17
- var __importDefault = (this && this.__importDefault) || function (mod) {
18
- return (mod && mod.__esModule) ? mod : { "default": mod };
19
- };
20
17
  Object.defineProperty(exports, "__esModule", { value: true });
21
18
  exports.ContextMenu = exports.sectionLevel = void 0;
22
- const style_guide_1 = require("@manuscripts/style-guide");
23
19
  const transform_1 = require("@manuscripts/transform");
24
20
  const prosemirror_utils_1 = require("prosemirror-utils");
25
21
  const commands_1 = require("../commands");
26
- const ReactSubView_1 = __importDefault(require("../views/ReactSubView"));
27
22
  const popper_1 = require("./popper");
28
23
  const popper = new popper_1.PopperManager();
29
24
  const listTypes = [transform_1.schema.nodes.ordered_list, transform_1.schema.nodes.bullet_list];
@@ -41,7 +36,7 @@ const hasAny = (set, ...items) => {
41
36
  return items.some((i) => set.has(i));
42
37
  };
43
38
  class ContextMenu {
44
- constructor(node, view, getPos, actions = {}, props) {
39
+ constructor(node, view, getPos, actions = {}) {
45
40
  this.showAddMenu = (target, after) => {
46
41
  const menu = document.createElement('div');
47
42
  menu.className = 'menu';
@@ -175,48 +170,11 @@ class ContextMenu {
175
170
  if (isInTable) {
176
171
  menu.appendChild(this.createMenuSection((section) => {
177
172
  section.appendChild(this.createMenuItem('Add Reference Note', () => {
178
- var _a;
179
173
  const footnotesElement = (0, prosemirror_utils_1.findChildrenByType)(this.node, transform_1.schema.nodes.footnotes_element);
180
174
  if (!footnotesElement.length) {
181
175
  const { state, dispatch } = this.view;
182
176
  (0, commands_1.insertTableFootnote)(this.node, this.getPos(), state, dispatch);
183
177
  }
184
- else {
185
- const footnotes = (0, prosemirror_utils_1.findChildrenByType)(footnotesElement[0].node, transform_1.schema.nodes.footnote).map((nodeWithPos) => {
186
- return nodeWithPos.node;
187
- });
188
- const targetDom = this.view.domAtPos(this.view.state.selection.from);
189
- if (targetDom.node instanceof Element && this.props) {
190
- const popperContainer = (0, ReactSubView_1.default)(Object.assign(Object.assign({}, this.props), { dispatch: this.view.dispatch }), style_guide_1.TableFootnotesSelector, {
191
- notes: footnotes,
192
- onAdd: () => {
193
- var _a;
194
- const { state, dispatch } = this.view;
195
- (0, commands_1.insertTableFootnote)(this.node, this.getPos(), state, dispatch);
196
- (_a = this.props) === null || _a === void 0 ? void 0 : _a.popper.destroy();
197
- },
198
- onInsert: (notes) => {
199
- var _a;
200
- const insertedAt = this.view.state.selection.to;
201
- const node = this.view.state.schema.nodes.inline_footnote.create({
202
- rids: notes.map((note) => note.attrs.id),
203
- contents: notes
204
- .map((_, index) => ++index)
205
- .join(),
206
- });
207
- const tr = this.view.state.tr;
208
- tr.insert(insertedAt, node);
209
- this.view.dispatch(tr);
210
- (_a = this.props) === null || _a === void 0 ? void 0 : _a.popper.destroy();
211
- },
212
- onCancel: () => {
213
- var _a;
214
- (_a = this.props) === null || _a === void 0 ? void 0 : _a.popper.destroy();
215
- },
216
- }, this.node, this.getPos, this.view, 'table-footnote-editor');
217
- (_a = this.props) === null || _a === void 0 ? void 0 : _a.popper.show(targetDom.node, popperContainer, 'bottom-end');
218
- }
219
- }
220
178
  }));
221
179
  }));
222
180
  }
@@ -337,7 +295,6 @@ class ContextMenu {
337
295
  this.view = view;
338
296
  this.getPos = getPos;
339
297
  this.actions = actions;
340
- this.props = props;
341
298
  }
342
299
  }
343
300
  exports.ContextMenu = ContextMenu;
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ /*!
3
+ * © 2024 Atypon Systems LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.findTableInlineFootnoteIds = void 0;
19
+ const transform_1 = require("@manuscripts/transform");
20
+ const prosemirror_utils_1 = require("prosemirror-utils");
21
+ const findTableInlineFootnoteIds = ($pos) => {
22
+ var _a;
23
+ const tableElement = (_a = (0, prosemirror_utils_1.findParentNodeClosestToPos)($pos, (node) => node.type === transform_1.schema.nodes.table_element)) === null || _a === void 0 ? void 0 : _a.node.firstChild;
24
+ return new Set(tableElement
25
+ ? (0, prosemirror_utils_1.findChildren)(tableElement, (node) => node.type === transform_1.schema.nodes.inline_footnote)
26
+ .map(({ node }) => node.attrs.rids)
27
+ .flat()
28
+ : []);
29
+ };
30
+ exports.findTableInlineFootnoteIds = findTableInlineFootnoteIds;
@@ -15,14 +15,16 @@
15
15
  * limitations under the License.
16
16
  */
17
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
- exports.buildPluginState = exports.footnotesKey = void 0;
18
+ exports.uncitedFootnoteWidget = exports.buildPluginState = exports.footnotesKey = void 0;
19
19
  const transform_1 = require("@manuscripts/transform");
20
20
  const lodash_1 = require("lodash");
21
21
  const prosemirror_state_1 = require("prosemirror-state");
22
22
  const prosemirror_utils_1 = require("prosemirror-utils");
23
23
  const prosemirror_view_1 = require("prosemirror-view");
24
+ const assets_1 = require("../../assets");
24
25
  const utils_1 = require("../../lib/utils");
25
26
  const placeholder_1 = require("../placeholder");
27
+ const footnotes_utils_1 = require("./footnotes-utils");
26
28
  exports.footnotesKey = new prosemirror_state_1.PluginKey('footnotes');
27
29
  const buildPluginState = (doc) => {
28
30
  const nodes = [];
@@ -59,6 +61,13 @@ const labelWidget = (label, id) => (view) => {
59
61
  });
60
62
  return element;
61
63
  };
64
+ const uncitedFootnoteWidget = () => () => {
65
+ const element = document.createElement('span');
66
+ element.className = 'unctied-table-footnote';
67
+ element.innerHTML = assets_1.alertIcon;
68
+ return element;
69
+ };
70
+ exports.uncitedFootnoteWidget = uncitedFootnoteWidget;
62
71
  exports.default = () => {
63
72
  return new prosemirror_state_1.Plugin({
64
73
  key: exports.footnotesKey,
@@ -101,7 +110,8 @@ exports.default = () => {
101
110
  }
102
111
  }
103
112
  const { labels } = exports.footnotesKey.getState(state);
104
- state.doc.descendants((node, pos) => {
113
+ let tableInlineFootnoteIds = undefined;
114
+ state.doc.descendants((node, pos, parent) => {
105
115
  var _a;
106
116
  if ((0, transform_1.isFootnoteNode)(node)) {
107
117
  const id = node.attrs.id;
@@ -116,11 +126,21 @@ exports.default = () => {
116
126
  if (!((_a = node.firstChild) === null || _a === void 0 ? void 0 : _a.textContent)) {
117
127
  decorations.push(prosemirror_view_1.Decoration.widget(pos + 2, (0, placeholder_1.placeholderWidget)('Add new note here')));
118
128
  }
129
+ if (tableInlineFootnoteIds &&
130
+ !tableInlineFootnoteIds.has(node.attrs.id)) {
131
+ decorations.push(prosemirror_view_1.Decoration.widget(pos + node.nodeSize - 1, (0, exports.uncitedFootnoteWidget)()));
132
+ }
119
133
  }
120
134
  if (node.type === transform_1.schema.nodes.footnotes_element) {
121
135
  decorations.push(prosemirror_view_1.Decoration.node(pos, pos + node.nodeSize, {
122
136
  class: 'footnote-element',
123
137
  }));
138
+ if ((parent === null || parent === void 0 ? void 0 : parent.type) === transform_1.schema.nodes.table_element_footer) {
139
+ tableInlineFootnoteIds = (0, footnotes_utils_1.findTableInlineFootnoteIds)(state.doc.resolve(pos));
140
+ }
141
+ else {
142
+ tableInlineFootnoteIds = undefined;
143
+ }
124
144
  }
125
145
  });
126
146
  return prosemirror_view_1.DecorationSet.create(state.doc, decorations);
@@ -117,7 +117,7 @@ const EditableBlock = (Base) => {
117
117
  const { setComment } = this.props;
118
118
  return new context_menu_1.ContextMenu(this.node, this.view, this.getPos, {
119
119
  setComment,
120
- }, this.props);
120
+ });
121
121
  };
122
122
  }
123
123
  };
package/dist/es/assets.js CHANGED
@@ -99,3 +99,19 @@ export const editAttrsTrackingIcon = `
99
99
  />
100
100
  </svg>
101
101
  `;
102
+ export const alertIcon = `
103
+ <svg
104
+ width="12"
105
+ height="12"
106
+ viewBox="0 0 12 12"
107
+ fill="none"
108
+ xmlns="http://www.w3.org/2000/svg"
109
+ >
110
+ <path
111
+ fill-rule="evenodd"
112
+ clip-rule="evenodd"
113
+ d="M6 12C2.68629 12 1.18852e-06 9.31371 1.47821e-06 6C1.7679e-06 2.68629 2.68629 1.39444e-07 6 4.29138e-07C9.31371 7.18831e-07 12 2.68629 12 6C12 9.31371 9.31371 12 6 12ZM6.74998 2.99996L6.75 6.37462C6.75 6.78819 6.41522 7.12243 6.00166 7.12334C5.58681 7.12426 5.25001 6.78821 5.25001 6.37335L5.25 3.00082C5.25 2.58629 5.58629 2.25037 6.00082 2.25083C6.4147 2.25128 6.74998 2.58607 6.74998 2.99996ZM6.75 8.99263C6.75 9.46884 6.47288 9.75 5.99853 9.75C5.52419 9.75 5.25 9.47179 5.25 8.99558C5.25 8.51937 5.52421 8.25 5.99855 8.25C6.47289 8.25 6.75 8.51642 6.75 8.99263Z"
114
+ fill="#FE8F1F"
115
+ />
116
+ </svg>
117
+ `;
@@ -660,37 +660,28 @@ export const insertTableFootnote = (node, position, state, dispatch) => {
660
660
  });
661
661
  const insertedAt = state.selection.to;
662
662
  const inlineFootnotes = findChildrenByType(node, schema.nodes.inline_footnote);
663
- const labels = inlineFootnotes.map((nodeWithPos) => nodeWithPos.node.attrs.contents);
664
663
  const inlineFootnoteNode = state.schema.nodes.inline_footnote.create({
665
664
  rids: [footnote.attrs.id],
666
- contents: labels.length ? Math.max(...labels) + 1 : 1,
665
+ contents: inlineFootnotes.length + 1,
667
666
  });
668
667
  const tr = state.tr;
669
668
  tr.insert(insertedAt, inlineFootnoteNode);
669
+ const footnoteElement = state.schema.nodes.footnotes_element.create({}, footnote);
670
+ const tableElementFooter = findChildrenByType(node, schema.nodes.table_element_footer);
670
671
  let insertionPos;
671
- const footnotesElement = findChildrenByType(node, schema.nodes.footnotes_element);
672
- if (footnotesElement.length) {
673
- const pos = footnotesElement[0].pos;
674
- insertionPos = position + pos + footnotesElement[0].node.nodeSize + 1;
675
- tr.insert(insertionPos, footnote);
672
+ if (tableElementFooter.length) {
673
+ const pos = tableElementFooter[0].pos;
674
+ insertionPos = position + pos + tableElementFooter[0].node.nodeSize + 1;
675
+ tr.insert(insertionPos, footnoteElement);
676
676
  }
677
677
  else {
678
- const footnoteElement = state.schema.nodes.footnotes_element.create({}, footnote);
679
- const tableElementFooter = findChildrenByType(node, schema.nodes.table_element_footer);
680
- if (tableElementFooter.length) {
681
- const pos = tableElementFooter[0].pos;
682
- insertionPos = position + pos + tableElementFooter[0].node.nodeSize + 1;
683
- tr.insert(insertionPos, footnoteElement);
684
- }
685
- else {
686
- const tableSize = (_a = node.content.firstChild) === null || _a === void 0 ? void 0 : _a.nodeSize;
687
- if (tableSize) {
688
- insertionPos = position + tableSize + 2;
689
- const tableElementFooter = schema.nodes.table_element_footer.create({
690
- id: generateID(ObjectTypes.TableElementFooter),
691
- }, [footnoteElement]);
692
- tr.insert(insertionPos, tableElementFooter);
693
- }
678
+ const tableSize = (_a = node.content.firstChild) === null || _a === void 0 ? void 0 : _a.nodeSize;
679
+ if (tableSize) {
680
+ insertionPos = position + tableSize + 2;
681
+ const tableElementFooter = schema.nodes.table_element_footer.create({
682
+ id: generateID(ObjectTypes.TableElementFooter),
683
+ }, [footnoteElement]);
684
+ tr.insert(insertionPos, tableElementFooter);
694
685
  }
695
686
  }
696
687
  if (dispatch && insertionPos) {
@@ -13,11 +13,9 @@
13
13
  * See the License for the specific language governing permissions and
14
14
  * limitations under the License.
15
15
  */
16
- import { TableFootnotesSelector } from '@manuscripts/style-guide';
17
16
  import { isInBibliographySection, nodeNames, schema, } from '@manuscripts/transform';
18
17
  import { findChildrenByType, hasParentNodeOfType } from 'prosemirror-utils';
19
18
  import { addComment, createBlock, insertTableFootnote } from '../commands';
20
- import ReactSubView from '../views/ReactSubView';
21
19
  import { PopperManager } from './popper';
22
20
  const popper = new PopperManager();
23
21
  const listTypes = [schema.nodes.ordered_list, schema.nodes.bullet_list];
@@ -34,7 +32,7 @@ const hasAny = (set, ...items) => {
34
32
  return items.some((i) => set.has(i));
35
33
  };
36
34
  export class ContextMenu {
37
- constructor(node, view, getPos, actions = {}, props) {
35
+ constructor(node, view, getPos, actions = {}) {
38
36
  this.showAddMenu = (target, after) => {
39
37
  const menu = document.createElement('div');
40
38
  menu.className = 'menu';
@@ -168,48 +166,11 @@ export class ContextMenu {
168
166
  if (isInTable) {
169
167
  menu.appendChild(this.createMenuSection((section) => {
170
168
  section.appendChild(this.createMenuItem('Add Reference Note', () => {
171
- var _a;
172
169
  const footnotesElement = findChildrenByType(this.node, schema.nodes.footnotes_element);
173
170
  if (!footnotesElement.length) {
174
171
  const { state, dispatch } = this.view;
175
172
  insertTableFootnote(this.node, this.getPos(), state, dispatch);
176
173
  }
177
- else {
178
- const footnotes = findChildrenByType(footnotesElement[0].node, schema.nodes.footnote).map((nodeWithPos) => {
179
- return nodeWithPos.node;
180
- });
181
- const targetDom = this.view.domAtPos(this.view.state.selection.from);
182
- if (targetDom.node instanceof Element && this.props) {
183
- const popperContainer = ReactSubView(Object.assign(Object.assign({}, this.props), { dispatch: this.view.dispatch }), TableFootnotesSelector, {
184
- notes: footnotes,
185
- onAdd: () => {
186
- var _a;
187
- const { state, dispatch } = this.view;
188
- insertTableFootnote(this.node, this.getPos(), state, dispatch);
189
- (_a = this.props) === null || _a === void 0 ? void 0 : _a.popper.destroy();
190
- },
191
- onInsert: (notes) => {
192
- var _a;
193
- const insertedAt = this.view.state.selection.to;
194
- const node = this.view.state.schema.nodes.inline_footnote.create({
195
- rids: notes.map((note) => note.attrs.id),
196
- contents: notes
197
- .map((_, index) => ++index)
198
- .join(),
199
- });
200
- const tr = this.view.state.tr;
201
- tr.insert(insertedAt, node);
202
- this.view.dispatch(tr);
203
- (_a = this.props) === null || _a === void 0 ? void 0 : _a.popper.destroy();
204
- },
205
- onCancel: () => {
206
- var _a;
207
- (_a = this.props) === null || _a === void 0 ? void 0 : _a.popper.destroy();
208
- },
209
- }, this.node, this.getPos, this.view, 'table-footnote-editor');
210
- (_a = this.props) === null || _a === void 0 ? void 0 : _a.popper.show(targetDom.node, popperContainer, 'bottom-end');
211
- }
212
- }
213
174
  }));
214
175
  }));
215
176
  }
@@ -330,6 +291,5 @@ export class ContextMenu {
330
291
  this.view = view;
331
292
  this.getPos = getPos;
332
293
  this.actions = actions;
333
- this.props = props;
334
294
  }
335
295
  }
@@ -0,0 +1,26 @@
1
+ /*!
2
+ * © 2024 Atypon Systems LLC
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ import { schema } from '@manuscripts/transform';
17
+ import { findChildren, findParentNodeClosestToPos } from 'prosemirror-utils';
18
+ export const findTableInlineFootnoteIds = ($pos) => {
19
+ var _a;
20
+ const tableElement = (_a = findParentNodeClosestToPos($pos, (node) => node.type === schema.nodes.table_element)) === null || _a === void 0 ? void 0 : _a.node.firstChild;
21
+ return new Set(tableElement
22
+ ? findChildren(tableElement, (node) => node.type === schema.nodes.inline_footnote)
23
+ .map(({ node }) => node.attrs.rids)
24
+ .flat()
25
+ : []);
26
+ };
@@ -18,8 +18,10 @@ import { isEqual } from 'lodash';
18
18
  import { NodeSelection, Plugin, PluginKey } from 'prosemirror-state';
19
19
  import { hasParentNodeOfType } from 'prosemirror-utils';
20
20
  import { Decoration, DecorationSet } from 'prosemirror-view';
21
+ import { alertIcon } from '../../assets';
21
22
  import { findParentNodeWithIdValue } from '../../lib/utils';
22
23
  import { placeholderWidget } from '../placeholder';
24
+ import { findTableInlineFootnoteIds } from './footnotes-utils';
23
25
  export const footnotesKey = new PluginKey('footnotes');
24
26
  export const buildPluginState = (doc) => {
25
27
  const nodes = [];
@@ -55,6 +57,12 @@ const labelWidget = (label, id) => (view) => {
55
57
  });
56
58
  return element;
57
59
  };
60
+ export const uncitedFootnoteWidget = () => () => {
61
+ const element = document.createElement('span');
62
+ element.className = 'unctied-table-footnote';
63
+ element.innerHTML = alertIcon;
64
+ return element;
65
+ };
58
66
  export default () => {
59
67
  return new Plugin({
60
68
  key: footnotesKey,
@@ -97,7 +105,8 @@ export default () => {
97
105
  }
98
106
  }
99
107
  const { labels } = footnotesKey.getState(state);
100
- state.doc.descendants((node, pos) => {
108
+ let tableInlineFootnoteIds = undefined;
109
+ state.doc.descendants((node, pos, parent) => {
101
110
  var _a;
102
111
  if (isFootnoteNode(node)) {
103
112
  const id = node.attrs.id;
@@ -112,11 +121,21 @@ export default () => {
112
121
  if (!((_a = node.firstChild) === null || _a === void 0 ? void 0 : _a.textContent)) {
113
122
  decorations.push(Decoration.widget(pos + 2, placeholderWidget('Add new note here')));
114
123
  }
124
+ if (tableInlineFootnoteIds &&
125
+ !tableInlineFootnoteIds.has(node.attrs.id)) {
126
+ decorations.push(Decoration.widget(pos + node.nodeSize - 1, uncitedFootnoteWidget()));
127
+ }
115
128
  }
116
129
  if (node.type === schema.nodes.footnotes_element) {
117
130
  decorations.push(Decoration.node(pos, pos + node.nodeSize, {
118
131
  class: 'footnote-element',
119
132
  }));
133
+ if ((parent === null || parent === void 0 ? void 0 : parent.type) === schema.nodes.table_element_footer) {
134
+ tableInlineFootnoteIds = findTableInlineFootnoteIds(state.doc.resolve(pos));
135
+ }
136
+ else {
137
+ tableInlineFootnoteIds = undefined;
138
+ }
120
139
  }
121
140
  });
122
141
  return DecorationSet.create(state.doc, decorations);
@@ -114,7 +114,7 @@ export const EditableBlock = (Base) => {
114
114
  const { setComment } = this.props;
115
115
  return new ContextMenu(this.node, this.view, this.getPos, {
116
116
  setComment,
117
- }, this.props);
117
+ });
118
118
  };
119
119
  }
120
120
  };
@@ -16,3 +16,4 @@
16
16
  export declare const editIcon = "\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 14 14\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M8.706 2.33624L11.553 5.19824L4.345 12.4422L1.498 9.58124L8.706 2.33624V2.33624ZM13.714 1.64624L12.444 0.37024C12.3273 0.253047 12.1886 0.160056 12.0359 0.0966039C11.8831 0.0331518 11.7194 0.000488281 11.554 0.000488281C11.3886 0.000488281 11.2249 0.0331518 11.0721 0.0966039C10.9194 0.160056 10.7807 0.253047 10.664 0.37024L9.447 1.59224L12.295 4.45424L13.715 3.02824C13.8976 2.84462 14.0001 2.59619 14.0001 2.33724C14.0001 2.07829 13.8976 1.82986 13.715 1.64624H13.714ZM0.00800253 13.6032C-0.00418388 13.6571 -0.00246802 13.7131 0.0129883 13.7661C0.0284447 13.819 0.0571327 13.8672 0.096349 13.906C0.135565 13.9448 0.184019 13.973 0.237143 13.9879C0.290268 14.0028 0.346315 14.004 0.400003 13.9912L3.573 13.2172L0.727003 10.3552L0.0070026 13.6032H0.00800253Z\"\n fill=\"#6E6E6E\"\n />\n </svg>\n";
17
17
  export declare const commentIcon = "\n<svg\n width=\"20\"\n height=\"15\"\n viewBox=\"0 0 20 15\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n fill-rule=\"evenodd\"\n clip-rule=\"evenodd\"\n d=\"M7.94841 4.18311C7.98238 3.9602 8 3.73191 8 3.49951C8 3.22073 7.97465 2.94787 7.92613 2.68311H13.5C14.8854 2.68311 16.25 3.6425 16.25 5.09977V9.02453L19.1086 12.9949C19.2731 13.2233 19.2958 13.5245 19.1675 13.775C19.0392 14.0255 18.7814 14.1831 18.5 14.1831H5.5C4.11463 14.1831 2.75 13.2237 2.75 11.7664V7.93729C2.9939 7.97821 3.24446 7.99951 3.5 7.99951C3.75553 7.99951 4.00609 7.97821 4.25 7.93729V11.7664C4.25 12.1508 4.67537 12.6831 5.5 12.6831H17.0358L14.8913 9.70467C14.7994 9.57703 14.75 9.42372 14.75 9.26644V5.09977C14.75 4.71538 14.3246 4.18311 13.5 4.18311H7.94841Z\"\n fill=\"#FFBD26\"\n />\n <path\n d=\"M11.5 6.99951H8.5\"\n stroke=\"#FFBD26\"\n stroke-width=\"1.5\"\n stroke-miterlimit=\"10\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n <path\n d=\"M12 9.99951H7\"\n stroke=\"#FFBD26\"\n stroke-width=\"1.5\"\n stroke-miterlimit=\"10\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n <path\n d=\"M3.5 1L3.5 6\"\n stroke=\"#FFBD26\"\n stroke-width=\"1.5\"\n stroke-miterlimit=\"10\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n <path\n d=\"M6 3.5L1 3.5\"\n stroke=\"#FFBD26\"\n stroke-width=\"1.5\"\n stroke-miterlimit=\"10\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n";
18
18
  export declare const editAttrsTrackingIcon = "\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M12 2L14 4L9 9L6 10L7 7L12 2Z\"\n stroke=\"#353535\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n <path\n d=\"M13 10V11.5C13 12.328 12.328 13 11.5 13H4.5C3.672 13 3 12.328 3 11.5V4.5C3 3.672 3.672 3 4.5 3H6\"\n stroke=\"#353535\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n";
19
+ export declare const alertIcon = "\n <svg\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 12 12\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n fill-rule=\"evenodd\"\n clip-rule=\"evenodd\"\n d=\"M6 12C2.68629 12 1.18852e-06 9.31371 1.47821e-06 6C1.7679e-06 2.68629 2.68629 1.39444e-07 6 4.29138e-07C9.31371 7.18831e-07 12 2.68629 12 6C12 9.31371 9.31371 12 6 12ZM6.74998 2.99996L6.75 6.37462C6.75 6.78819 6.41522 7.12243 6.00166 7.12334C5.58681 7.12426 5.25001 6.78821 5.25001 6.37335L5.25 3.00082C5.25 2.58629 5.58629 2.25037 6.00082 2.25083C6.4147 2.25128 6.74998 2.58607 6.74998 2.99996ZM6.75 8.99263C6.75 9.46884 6.47288 9.75 5.99853 9.75C5.52419 9.75 5.25 9.47179 5.25 8.99558C5.25 8.51937 5.52421 8.25 5.99855 8.25C6.47289 8.25 6.75 8.51642 6.75 8.99263Z\"\n fill=\"#FE8F1F\"\n />\n </svg>\n";
@@ -15,7 +15,6 @@
15
15
  */
16
16
  import { CommentAnnotation } from '@manuscripts/json-schema';
17
17
  import { ManuscriptEditorView, ManuscriptNode } from '@manuscripts/transform';
18
- import { EditableBlockProps } from '../views/editable_block';
19
18
  export declare const sectionLevel: (depth: number) => string;
20
19
  interface Actions {
21
20
  setComment?: (comment: CommentAnnotation) => void;
@@ -25,8 +24,7 @@ export declare class ContextMenu {
25
24
  private readonly view;
26
25
  private readonly getPos;
27
26
  private readonly actions;
28
- private readonly props?;
29
- constructor(node: ManuscriptNode, view: ManuscriptEditorView, getPos: () => number, actions?: Actions, props?: EditableBlockProps);
27
+ constructor(node: ManuscriptNode, view: ManuscriptEditorView, getPos: () => number, actions?: Actions);
30
28
  showAddMenu: (target: Element, after: boolean) => void;
31
29
  showEditMenu: (target: Element) => void;
32
30
  private createMenuItem;
@@ -0,0 +1,17 @@
1
+ /*!
2
+ * © 2024 Atypon Systems LLC
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ import { ResolvedPos } from 'prosemirror-model';
17
+ export declare const findTableInlineFootnoteIds: ($pos: ResolvedPos) => Set<string>;
@@ -21,5 +21,6 @@ interface PluginState {
21
21
  }
22
22
  export declare const footnotesKey: PluginKey<PluginState>;
23
23
  export declare const buildPluginState: (doc: ManuscriptNode) => PluginState;
24
+ export declare const uncitedFootnoteWidget: () => () => HTMLSpanElement;
24
25
  declare const _default: () => Plugin<PluginState>;
25
26
  export default _default;
@@ -26,7 +26,7 @@ export interface EditableBlockProps extends BaseNodeProps {
26
26
  retrySync: (componentIDs: string[]) => Promise<void>;
27
27
  setComment: (comment: CommentAnnotation) => void;
28
28
  dispatch?: Dispatch;
29
- theme: DefaultTheme;
29
+ theme?: DefaultTheme;
30
30
  }
31
31
  export declare const EditableBlock: <T extends Constructor<BlockView<EditableBlockProps>>>(Base: T) => {
32
32
  new (...args: any[]): {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@manuscripts/body-editor",
3
3
  "description": "Prosemirror components for editing and viewing manuscripts",
4
- "version": "1.7.8-LEAN-3160-2",
4
+ "version": "1.7.9",
5
5
  "repository": "github:Atypon-OpenSource/manuscripts-body-editor",
6
6
  "license": "Apache-2.0",
7
7
  "main": "dist/cjs",
@@ -29,11 +29,11 @@
29
29
  "dependencies": {
30
30
  "@iarna/word-count": "^1.1.2",
31
31
  "@manuscripts/assets": "^0.6.4",
32
- "@manuscripts/json-schema": "^2.2.2",
33
- "@manuscripts/library": "1.3.2",
34
- "@manuscripts/style-guide": "1.7.5-LEAN-3160-1",
32
+ "@manuscripts/json-schema": "^2.2.4",
33
+ "@manuscripts/library": "^1.3.3",
34
+ "@manuscripts/style-guide": "^1.7.6",
35
35
  "@manuscripts/track-changes-plugin": "^1.7.5",
36
- "@manuscripts/transform": "2.1.1",
36
+ "@manuscripts/transform": "^2.1.2",
37
37
  "astrocite-eutils": "^0.16.4",
38
38
  "axios": "^1.6.7",
39
39
  "codemirror": "^5.58.1",
@@ -109,4 +109,4 @@
109
109
  "resolutions": {
110
110
  "@types/react": "^17.0.2"
111
111
  }
112
- }
112
+ }
package/styles/Editor.css CHANGED
@@ -955,7 +955,7 @@
955
955
  counter-reset: table_footnote;
956
956
  }
957
957
 
958
- .ProseMirror .table-footer .footnote-element p::before {
958
+ .ProseMirror .table-footer .footnote-element > div:not(:has(.unctied-table-footnote)) p::before {
959
959
  counter-increment: table_footnote;
960
960
  content: counter(table_footnote);
961
961
  display: inline-block;
@@ -998,6 +998,18 @@
998
998
  cursor: pointer;
999
999
  }
1000
1000
 
1001
+ .ProseMirror .footnote-element > div:has(.unctied-table-footnote) {
1002
+ position: relative;
1003
+ }
1004
+
1005
+ .ProseMirror .unctied-table-footnote {
1006
+ display: flex;
1007
+ position: absolute;
1008
+ margin-right: 4px;
1009
+ top: 10%;
1010
+ right: 100%;
1011
+ }
1012
+
1001
1013
  .graphical-abstract .listing {
1002
1014
  display: none;
1003
1015
  }
package/styles/popper.css CHANGED
@@ -135,8 +135,7 @@
135
135
  .popper .citation-editor,
136
136
  .popper .cross-reference-editor,
137
137
  .popper .citation-references,
138
- .popper .track-changes-review-panel,
139
- .popper .table-footnote-editor {
138
+ .popper .track-changes-review-panel {
140
139
  background: #fff;
141
140
  border: 1px solid #e2e2e2;
142
141
  border-radius: 8px;
@@ -190,8 +189,7 @@
190
189
  height: auto;
191
190
  }
192
191
 
193
- .popper .citation-editor,
194
- .popper .table-footnote-editor {
192
+ .popper .citation-editor {
195
193
  width: 600px;
196
194
  }
197
195
 
@@ -206,8 +204,7 @@
206
204
  .popper .citation-editor,
207
205
  .popper .cross-reference-editor,
208
206
  .popper .equation-editor,
209
- .popper .link-editor,
210
- .popper .table-footnote-editor {
207
+ .popper .link-editor {
211
208
  min-width: 90%;
212
209
  max-width: 90%;
213
210
  }
@@ -222,10 +219,6 @@
222
219
  width: 600px;
223
220
  }
224
221
 
225
- .popper .table-footnote-editor {
226
- left: 50%;
227
- transform: translate(-50%, -100%);
228
- }
229
222
 
230
223
  .popper .track-attrs-popper {
231
224
  box-shadow: 0 4px 9px 0 rgba(0, 0, 0, 0.30);