@manuscripts/body-editor 1.7.15 → 1.7.16-LEAN-3405-0

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.
Files changed (35) hide show
  1. package/dist/cjs/commands.js +9 -7
  2. package/dist/cjs/lib/context-menu.js +8 -5
  3. package/dist/cjs/lib/helpers.js +44 -1
  4. package/dist/cjs/lib/mathml-to-svg.js +70 -0
  5. package/dist/cjs/lib/tex-to-svg.js +60 -0
  6. package/dist/cjs/plugins/footnotes/index.js +0 -3
  7. package/dist/cjs/views/equation.js +21 -13
  8. package/dist/cjs/views/equation_editable.js +5 -9
  9. package/dist/cjs/views/equation_element.js +6 -3
  10. package/dist/cjs/views/footnotes_element.js +19 -1
  11. package/dist/cjs/views/footnotes_element_editable.js +1 -1
  12. package/dist/cjs/views/inline_equation.js +21 -13
  13. package/dist/cjs/views/inline_equation_editable.js +5 -9
  14. package/dist/cjs/views/inline_footnote.js +5 -0
  15. package/dist/es/commands.js +10 -8
  16. package/dist/es/lib/context-menu.js +8 -5
  17. package/dist/es/lib/helpers.js +19 -0
  18. package/dist/es/lib/mathml-to-svg.js +66 -0
  19. package/dist/es/lib/tex-to-svg.js +56 -0
  20. package/dist/es/plugins/footnotes/index.js +0 -3
  21. package/dist/es/views/equation.js +21 -13
  22. package/dist/es/views/equation_editable.js +5 -9
  23. package/dist/es/views/equation_element.js +6 -3
  24. package/dist/es/views/footnotes_element.js +20 -2
  25. package/dist/es/views/footnotes_element_editable.js +2 -2
  26. package/dist/es/views/inline_equation.js +21 -13
  27. package/dist/es/views/inline_equation_editable.js +5 -9
  28. package/dist/es/views/inline_footnote.js +5 -0
  29. package/dist/types/lib/helpers.d.ts +1 -0
  30. package/dist/types/lib/mathml-to-svg.d.ts +17 -0
  31. package/dist/types/lib/tex-to-svg.d.ts +18 -0
  32. package/dist/types/views/footnotes_element.d.ts +3 -1
  33. package/dist/types/views/footnotes_element_editable.d.ts +1 -1
  34. package/package.json +6 -5
  35. package/styles/Editor.css +12 -2
@@ -26,6 +26,7 @@ const prosemirror_transform_1 = require("prosemirror-transform");
26
26
  const prosemirror_utils_1 = require("prosemirror-utils");
27
27
  const list_1 = require("./keys/list");
28
28
  const helpers_1 = require("./lib/helpers");
29
+ const track_changes_utils_1 = require("./lib/track-changes-utils");
29
30
  const utils_1 = require("./lib/utils");
30
31
  const comment_annotation_1 = require("./plugins/comment_annotation");
31
32
  const highlight_1 = require("./plugins/highlight");
@@ -109,7 +110,6 @@ const createBlock = (nodeType, position, state, dispatch) => {
109
110
  case state.schema.nodes.equation_element:
110
111
  node = state.schema.nodes.equation_element.create({}, [
111
112
  state.schema.nodes.equation.create(),
112
- createAndFillFigcaptionElement(state),
113
113
  ]);
114
114
  break;
115
115
  default:
@@ -290,10 +290,10 @@ const insertCrossReference = (state, dispatch) => {
290
290
  };
291
291
  exports.insertCrossReference = insertCrossReference;
292
292
  const insertInlineEquation = (state, dispatch) => {
293
- const inlineMathFragment = (0, transform_1.buildInlineMathFragment)(state.selection.$anchor.parent.attrs.id, selectedText().replace(/^\$/, '').replace(/\$$/, ''));
294
293
  const sourcePos = state.selection.from - 1;
295
294
  const tr = state.tr.replaceSelectionWith(state.schema.nodes.inline_equation.create({
296
- id: inlineMathFragment._id,
295
+ format: 'tex',
296
+ contents: selectedText().replace(/^\$/, '').replace(/\$$/, ''),
297
297
  }));
298
298
  if (dispatch) {
299
299
  const selection = prosemirror_state_1.NodeSelection.create(tr.doc, tr.mapping.map(sourcePos) + 1);
@@ -738,10 +738,12 @@ const insertTableFootnote = (node, position, state, dispatch) => {
738
738
  const tr = state.tr;
739
739
  tr.insert(insertedAt, inlineFootnoteNode);
740
740
  let insertionPos;
741
- const footnotesElement = (0, prosemirror_utils_1.findChildrenByType)(node, transform_1.schema.nodes.footnotes_element);
742
- if (footnotesElement.length) {
743
- const pos = footnotesElement[0].pos;
744
- insertionPos = position + pos + footnotesElement[0].node.nodeSize + 1;
741
+ const footnotesElement = (0, prosemirror_utils_1.findChildrenByType)(node, transform_1.schema.nodes.footnotes_element).pop();
742
+ if (footnotesElement &&
743
+ !(0, track_changes_utils_1.isDeleted)(footnotesElement.node) &&
744
+ !(0, track_changes_utils_1.isRejectedInsert)(footnotesElement.node)) {
745
+ const pos = footnotesElement.pos;
746
+ insertionPos = position + pos + footnotesElement.node.nodeSize + 1;
745
747
  tr.insert(insertionPos, footnote);
746
748
  }
747
749
  else {
@@ -25,6 +25,7 @@ const prosemirror_utils_1 = require("prosemirror-utils");
25
25
  const commands_1 = require("../commands");
26
26
  const ReactSubView_1 = __importDefault(require("../views/ReactSubView"));
27
27
  const popper_1 = require("./popper");
28
+ const track_changes_utils_1 = require("./track-changes-utils");
28
29
  const popper = new popper_1.PopperManager();
29
30
  const listTypes = [transform_1.schema.nodes.ordered_list, transform_1.schema.nodes.bullet_list];
30
31
  const readonlyTypes = [transform_1.schema.nodes.keywords, transform_1.schema.nodes.bibliography_element];
@@ -186,14 +187,16 @@ class ContextMenu {
186
187
  if (isInTable) {
187
188
  menu.appendChild(this.createMenuSection((section) => {
188
189
  section.appendChild(this.createMenuItem('Add Reference Note', () => {
189
- var _a;
190
- const footnotesElement = (0, prosemirror_utils_1.findChildrenByType)(this.node, transform_1.schema.nodes.footnotes_element);
191
- if (!footnotesElement.length) {
190
+ var _a, _b;
191
+ const footnotesElement = (_a = (0, prosemirror_utils_1.findChildrenByType)(this.node, transform_1.schema.nodes.footnotes_element).pop()) === null || _a === void 0 ? void 0 : _a.node;
192
+ if (!footnotesElement ||
193
+ (0, track_changes_utils_1.isDeleted)(footnotesElement) ||
194
+ (0, track_changes_utils_1.isRejectedInsert)(footnotesElement)) {
192
195
  const { state, dispatch } = this.view;
193
196
  (0, commands_1.insertTableFootnote)(this.node, this.getPos(), state, dispatch);
194
197
  }
195
198
  else {
196
- const footnotes = (0, prosemirror_utils_1.findChildrenByType)(footnotesElement[0].node, transform_1.schema.nodes.footnote).map((nodeWithPos) => {
199
+ const footnotes = (0, prosemirror_utils_1.findChildrenByType)(footnotesElement, transform_1.schema.nodes.footnote).map((nodeWithPos) => {
197
200
  return nodeWithPos.node;
198
201
  });
199
202
  const targetDom = this.view.domAtPos(this.view.state.selection.from);
@@ -225,7 +228,7 @@ class ContextMenu {
225
228
  (_a = this.props) === null || _a === void 0 ? void 0 : _a.popper.destroy();
226
229
  },
227
230
  }, this.node, this.getPos, this.view, 'table-footnote-editor');
228
- (_a = this.props) === null || _a === void 0 ? void 0 : _a.popper.show(targetDom.node, popperContainer, 'bottom-end');
231
+ (_b = this.props) === null || _b === void 0 ? void 0 : _b.popper.show(targetDom.node, popperContainer, 'bottom-end');
229
232
  }
230
233
  }
231
234
  }));
@@ -14,8 +14,40 @@
14
14
  * See the License for the specific language governing permissions and
15
15
  * limitations under the License.
16
16
  */
17
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
18
+ if (k2 === undefined) k2 = k;
19
+ var desc = Object.getOwnPropertyDescriptor(m, k);
20
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
21
+ desc = { enumerable: true, get: function() { return m[k]; } };
22
+ }
23
+ Object.defineProperty(o, k2, desc);
24
+ }) : (function(o, m, k, k2) {
25
+ if (k2 === undefined) k2 = k;
26
+ o[k2] = m[k];
27
+ }));
28
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
29
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
30
+ }) : function(o, v) {
31
+ o["default"] = v;
32
+ });
33
+ var __importStar = (this && this.__importStar) || function (mod) {
34
+ if (mod && mod.__esModule) return mod;
35
+ var result = {};
36
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
37
+ __setModuleDefault(result, mod);
38
+ return result;
39
+ };
40
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
41
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
42
+ return new (P || (P = Promise))(function (resolve, reject) {
43
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
44
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
45
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
46
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
47
+ });
48
+ };
17
49
  Object.defineProperty(exports, "__esModule", { value: true });
18
- exports.mergeSimilarItems = exports.nearestAncestor = exports.isNodeOfType = void 0;
50
+ exports.renderMath = exports.mergeSimilarItems = exports.nearestAncestor = exports.isNodeOfType = void 0;
19
51
  const isNodeOfType = (...type) => (node) => {
20
52
  const [head, ...tail] = type;
21
53
  if (node.type === node.type.schema.nodes[head]) {
@@ -50,3 +82,14 @@ const mergeSimilarItems = (compareFunc, mergeFunc) => (items) => {
50
82
  }, []);
51
83
  };
52
84
  exports.mergeSimilarItems = mergeSimilarItems;
85
+ const renderMath = (math, format) => __awaiter(void 0, void 0, void 0, function* () {
86
+ if (format === 'tex') {
87
+ const { convertTeXToSVG } = yield Promise.resolve().then(() => __importStar(require('../lib/tex-to-svg')));
88
+ return convertTeXToSVG(math);
89
+ }
90
+ else {
91
+ const { convertMathMLToSVG } = yield Promise.resolve().then(() => __importStar(require('../lib/mathml-to-svg')));
92
+ return convertMathMLToSVG(math);
93
+ }
94
+ });
95
+ exports.renderMath = renderMath;
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ /*!
3
+ * © 2019 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.convertMathMLToSVG = void 0;
19
+ require("mathjax-full/js/util/entities/all");
20
+ const transform_1 = require("@manuscripts/transform");
21
+ const HTMLAdaptor_1 = require("mathjax-full/js/adaptors/HTMLAdaptor");
22
+ const MmlFactory_1 = require("mathjax-full/js/core/MmlTree/MmlFactory");
23
+ const HTMLDocument_1 = require("mathjax-full/js/handlers/html/HTMLDocument");
24
+ const mathml_1 = require("mathjax-full/js/input/mathml");
25
+ const svg_1 = require("mathjax-full/js/output/svg");
26
+ class ManuscriptsMmlFactory extends MmlFactory_1.MmlFactory {
27
+ constructor() {
28
+ super();
29
+ this.nodeMap.set('image', this.nodeMap.get('none'));
30
+ }
31
+ create(kind, properties = {}, children = []) {
32
+ if (kind === 'image') {
33
+ return this.node['none'](properties, children);
34
+ }
35
+ return this.node[kind](properties, children);
36
+ }
37
+ }
38
+ class ManuscriptsHTMLAdaptor extends HTMLAdaptor_1.HTMLAdaptor {
39
+ setAttribute(node, name, value, ns) {
40
+ if (name !== 'xmlns') {
41
+ ns ? node.setAttributeNS(ns, name, value) : node.setAttribute(name, value);
42
+ }
43
+ }
44
+ }
45
+ const InputJax = new mathml_1.MathML();
46
+ const OutputJax = new svg_1.SVG({
47
+ fontCache: 'none',
48
+ });
49
+ const adaptor = new ManuscriptsHTMLAdaptor(window);
50
+ const doc = new HTMLDocument_1.HTMLDocument(document, adaptor, {
51
+ InputJax,
52
+ OutputJax,
53
+ MmlFactory: new ManuscriptsMmlFactory(),
54
+ });
55
+ doc.addStyleSheet();
56
+ const convertMathMLToSVG = (mathml, display = true) => {
57
+ const item = doc.convert(mathml, {
58
+ display,
59
+ em: 16,
60
+ ex: 8,
61
+ containerWidth: 1000000,
62
+ lineWidth: 1000000,
63
+ scale: 1,
64
+ });
65
+ if (!item || !item.firstChild) {
66
+ return null;
67
+ }
68
+ return transform_1.xmlSerializer.serializeToString(item.firstChild);
69
+ };
70
+ exports.convertMathMLToSVG = convertMathMLToSVG;
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ /*!
3
+ * © 2019 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.convertTeXToSVG = exports.packages = void 0;
19
+ require("mathjax-full/js/util/entities/all");
20
+ const transform_1 = require("@manuscripts/transform");
21
+ const HTMLAdaptor_1 = require("mathjax-full/js/adaptors/HTMLAdaptor");
22
+ const HTMLDocument_1 = require("mathjax-full/js/handlers/html/HTMLDocument");
23
+ const tex_1 = require("mathjax-full/js/input/tex");
24
+ const AllPackages_1 = require("mathjax-full/js/input/tex/AllPackages");
25
+ const svg_1 = require("mathjax-full/js/output/svg");
26
+ exports.packages = AllPackages_1.AllPackages.filter((name) => name !== 'html' && name !== 'bussproofs');
27
+ class ManuscriptsHTMLAdaptor extends HTMLAdaptor_1.HTMLAdaptor {
28
+ setAttribute(node, name, value, ns) {
29
+ if (name !== 'xmlns') {
30
+ ns ? node.setAttributeNS(ns, name, value) : node.setAttribute(name, value);
31
+ }
32
+ }
33
+ }
34
+ const InputJax = new tex_1.TeX({
35
+ packages: exports.packages,
36
+ });
37
+ const OutputJax = new svg_1.SVG({
38
+ fontCache: 'none',
39
+ });
40
+ const adaptor = new ManuscriptsHTMLAdaptor(window);
41
+ const doc = new HTMLDocument_1.HTMLDocument(document, adaptor, {
42
+ InputJax,
43
+ OutputJax,
44
+ });
45
+ doc.addStyleSheet();
46
+ const convertTeXToSVG = (tex, display = true) => {
47
+ const item = doc.convert(tex, {
48
+ display,
49
+ em: 16,
50
+ ex: 8,
51
+ containerWidth: 1000000,
52
+ lineWidth: 1000000,
53
+ scale: 1,
54
+ });
55
+ if (!item || !item.firstChild) {
56
+ return null;
57
+ }
58
+ return transform_1.xmlSerializer.serializeToString(item.firstChild);
59
+ };
60
+ exports.convertTeXToSVG = convertTeXToSVG;
@@ -132,9 +132,6 @@ exports.default = () => {
132
132
  }
133
133
  }
134
134
  if (node.type === transform_1.schema.nodes.footnotes_element) {
135
- decorations.push(prosemirror_view_1.Decoration.node(pos, pos + node.nodeSize, {
136
- class: 'footnote-element',
137
- }));
138
135
  if ((parent === null || parent === void 0 ? void 0 : parent.type) === transform_1.schema.nodes.table_element_footer) {
139
136
  tableInlineFootnoteIds = (0, footnotes_utils_1.findTableInlineFootnoteIds)(state.doc.resolve(pos));
140
137
  }
@@ -17,6 +17,7 @@
17
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
18
  exports.EquationView = void 0;
19
19
  const dompurify_1 = require("../lib/dompurify");
20
+ const helpers_1 = require("../lib/helpers");
20
21
  const base_node_view_1 = require("./base_node_view");
21
22
  const creators_1 = require("./creators");
22
23
  class EquationView extends base_node_view_1.BaseNodeView {
@@ -32,22 +33,29 @@ class EquationView extends base_node_view_1.BaseNodeView {
32
33
  this.dom.setAttribute('id', this.node.attrs.id);
33
34
  };
34
35
  this.updateContents = () => {
35
- const { SVGStringRepresentation } = this.node.attrs;
36
+ const { contents, format } = this.node.attrs;
36
37
  while (this.dom.hasChildNodes()) {
37
38
  this.dom.removeChild(this.dom.firstChild);
38
39
  }
39
- if (SVGStringRepresentation) {
40
- const fragment = (0, dompurify_1.sanitize)(SVGStringRepresentation, {
41
- USE_PROFILES: { svg: true },
42
- });
43
- this.dom.appendChild(fragment);
44
- }
45
- else {
46
- const placeholder = document.createElement('div');
47
- placeholder.className = 'equation-placeholder';
48
- placeholder.textContent = '<Equation>';
49
- this.dom.appendChild(placeholder);
50
- }
40
+ (0, helpers_1.renderMath)(contents, format)
41
+ .then((svgContent) => {
42
+ if (svgContent) {
43
+ const fragment = (0, dompurify_1.sanitize)(svgContent, {
44
+ USE_PROFILES: { svg: true },
45
+ });
46
+ this.dom.appendChild(fragment);
47
+ }
48
+ else {
49
+ const placeholder = document.createElement('div');
50
+ placeholder.className = 'equation-placeholder';
51
+ placeholder.textContent = '<Equation>';
52
+ this.dom.appendChild(placeholder);
53
+ }
54
+ return true;
55
+ })
56
+ .catch((error) => {
57
+ console.error(error);
58
+ });
51
59
  };
52
60
  this.ignoreMutation = () => true;
53
61
  }
@@ -48,7 +48,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
48
48
  };
49
49
  Object.defineProperty(exports, "__esModule", { value: true });
50
50
  exports.EquationEditableView = void 0;
51
- const transform_1 = require("@manuscripts/transform");
52
51
  const prosemirror_state_1 = require("prosemirror-state");
53
52
  const creators_1 = require("./creators");
54
53
  const equation_1 = require("./equation");
@@ -62,21 +61,18 @@ class EquationEditableView extends equation_1.EquationView {
62
61
  const { createEditor } = yield Promise.resolve().then(() => __importStar(require('../lib/codemirror')));
63
62
  const placeholder = 'Enter LaTeX equation, e.g. "a^2 = \\sqrt{b^2 + c^2}"';
64
63
  const input = yield createEditor({
65
- value: this.node.attrs.TeXRepresentation || '',
64
+ value: this.node.attrs.contents || '',
66
65
  mode: 'stex',
67
66
  placeholder,
68
67
  autofocus: true,
69
68
  });
70
69
  input.on('changes', () => __awaiter(this, void 0, void 0, function* () {
71
- const TeXRepresentation = input.getValue();
72
- const SVGStringRepresentation = yield (0, transform_1.convertTeXToSVG)(TeXRepresentation, true);
73
- if (!SVGStringRepresentation) {
74
- throw new Error('No SVG output from MathJax');
75
- }
70
+ const contents = input.getValue();
76
71
  const pos = this.getPos();
77
72
  const { tr } = this.view.state;
78
- tr.setNodeMarkup(pos, undefined, Object.assign(Object.assign({}, this.node.attrs), { TeXRepresentation,
79
- SVGStringRepresentation })).setSelection(prosemirror_state_1.NodeSelection.create(tr.doc, pos));
73
+ const format = contents.includes('mml:math') ? 'mathml' : 'tex';
74
+ tr.setNodeMarkup(pos, undefined, Object.assign(Object.assign({}, this.node.attrs), { contents,
75
+ format })).setSelection(prosemirror_state_1.NodeSelection.create(tr.doc, pos));
80
76
  this.view.dispatch(tr);
81
77
  }));
82
78
  const wrapper = document.createElement('div');
@@ -27,9 +27,12 @@ class EquationElementView extends block_view_1.default {
27
27
  this.elementType = 'figure';
28
28
  this.updateContents = () => {
29
29
  var _a;
30
- const { suppressCaption, suppressTitle } = this.node.attrs;
31
- this.dom.classList.toggle('suppress-caption', suppressCaption);
32
- this.dom.classList.toggle('suppress-title', suppressTitle === undefined ? true : suppressTitle);
30
+ const { label } = this.node.attrs;
31
+ if (label) {
32
+ const labelEl = document.createElement('label');
33
+ labelEl.textContent = label;
34
+ this.dom.appendChild(labelEl);
35
+ }
33
36
  if ((_a = this.node.attrs.dataTracked) === null || _a === void 0 ? void 0 : _a.length) {
34
37
  const lastChange = this.node.attrs.dataTracked[this.node.attrs.dataTracked.length - 1];
35
38
  this.dom.setAttribute('data-track-status', lastChange.status);
@@ -19,22 +19,40 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
19
19
  };
20
20
  Object.defineProperty(exports, "__esModule", { value: true });
21
21
  exports.FootnotesElementView = void 0;
22
+ const transform_1 = require("@manuscripts/transform");
23
+ const track_changes_utils_1 = require("../lib/track-changes-utils");
22
24
  const block_view_1 = __importDefault(require("./block_view"));
23
25
  const creators_1 = require("./creators");
24
26
  class FootnotesElementView extends block_view_1.default {
25
27
  constructor() {
26
28
  super(...arguments);
27
29
  this.elementType = 'div';
30
+ this.updateContents = () => {
31
+ const $pos = this.view.state.doc.resolve(this.getPos());
32
+ if ($pos.parent.type === transform_1.schema.nodes.table_element_footer) {
33
+ this.setTCClasses();
34
+ }
35
+ };
28
36
  this.checkEditability = () => {
29
37
  var _a, _b;
30
38
  const editable = this.node.childCount ? 'true' : 'false';
31
39
  (_a = this.contentDOM) === null || _a === void 0 ? void 0 : _a.setAttribute('contenteditable', editable);
32
40
  (_b = this.dom) === null || _b === void 0 ? void 0 : _b.setAttribute('contenteditable', editable);
33
41
  };
42
+ this.setTCClasses = () => {
43
+ const classNames = ['footnote-element'];
44
+ const dataTracked = this.node.attrs.dataTracked;
45
+ if (dataTracked === null || dataTracked === void 0 ? void 0 : dataTracked.length) {
46
+ const lastChange = dataTracked[dataTracked.length - 1];
47
+ const changeClasses = (0, track_changes_utils_1.getChangeClasses)([lastChange]);
48
+ classNames.push(...changeClasses);
49
+ }
50
+ this.dom.className = classNames.join(' ');
51
+ };
34
52
  }
35
53
  onUpdateContent() {
36
54
  this.checkEditability();
37
55
  }
38
56
  }
39
57
  exports.FootnotesElementView = FootnotesElementView;
40
- exports.default = (0, creators_1.createNodeOrElementView)(FootnotesElementView, 'div');
58
+ exports.default = (0, creators_1.createNodeView)(FootnotesElementView);
@@ -18,4 +18,4 @@ Object.defineProperty(exports, "__esModule", { value: true });
18
18
  const creators_1 = require("./creators");
19
19
  const editable_block_1 = require("./editable_block");
20
20
  const footnotes_element_1 = require("./footnotes_element");
21
- exports.default = (0, creators_1.createNodeOrElementView)((0, editable_block_1.EditableBlock)(footnotes_element_1.FootnotesElementView), 'div');
21
+ exports.default = (0, creators_1.createNodeView)((0, editable_block_1.EditableBlock)(footnotes_element_1.FootnotesElementView));
@@ -17,6 +17,7 @@
17
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
18
  exports.InlineEquationView = void 0;
19
19
  const dompurify_1 = require("../lib/dompurify");
20
+ const helpers_1 = require("../lib/helpers");
20
21
  const track_changes_utils_1 = require("../lib/track-changes-utils");
21
22
  const base_node_view_1 = require("./base_node_view");
22
23
  const creators_1 = require("./creators");
@@ -29,22 +30,29 @@ class InlineEquationView extends base_node_view_1.BaseNodeView {
29
30
  };
30
31
  this.updateContents = () => {
31
32
  if (!(0, track_changes_utils_1.isRejectedInsert)(this.node)) {
32
- const { SVGRepresentation } = this.node.attrs;
33
+ const { contents, format } = this.node.attrs;
33
34
  while (this.dom.hasChildNodes()) {
34
35
  this.dom.removeChild(this.dom.firstChild);
35
36
  }
36
- if (SVGRepresentation) {
37
- const fragment = (0, dompurify_1.sanitize)(SVGRepresentation, {
38
- USE_PROFILES: { svg: true },
39
- });
40
- this.dom.appendChild(fragment);
41
- }
42
- else {
43
- const placeholder = document.createElement('div');
44
- placeholder.className = 'equation-placeholder';
45
- placeholder.textContent = '<Equation>';
46
- this.dom.appendChild(placeholder);
47
- }
37
+ (0, helpers_1.renderMath)(contents, format)
38
+ .then((svgContent) => {
39
+ if (svgContent) {
40
+ const fragment = (0, dompurify_1.sanitize)(svgContent, {
41
+ USE_PROFILES: { svg: true },
42
+ });
43
+ this.dom.appendChild(fragment);
44
+ }
45
+ else {
46
+ const placeholder = document.createElement('div');
47
+ placeholder.className = 'equation-placeholder';
48
+ placeholder.textContent = '<Equation>';
49
+ this.dom.appendChild(placeholder);
50
+ }
51
+ return true;
52
+ })
53
+ .catch((error) => {
54
+ console.error(error);
55
+ });
48
56
  }
49
57
  else {
50
58
  this.dom.innerHTML = '';
@@ -48,7 +48,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
48
48
  };
49
49
  Object.defineProperty(exports, "__esModule", { value: true });
50
50
  exports.InlineEquationEditableView = void 0;
51
- const transform_1 = require("@manuscripts/transform");
52
51
  const prosemirror_state_1 = require("prosemirror-state");
53
52
  const creators_1 = require("./creators");
54
53
  const inline_equation_1 = require("./inline_equation");
@@ -62,21 +61,18 @@ class InlineEquationEditableView extends inline_equation_1.InlineEquationView {
62
61
  const { createEditor } = yield Promise.resolve().then(() => __importStar(require('../lib/codemirror')));
63
62
  const placeholder = 'Enter LaTeX equation, e.g. "E=mc^2"';
64
63
  const input = yield createEditor({
65
- value: this.node.attrs.TeXRepresentation || '',
64
+ value: this.node.attrs.contents || '',
66
65
  mode: 'stex',
67
66
  placeholder,
68
67
  autofocus: true,
69
68
  });
70
69
  input.on('changes', () => __awaiter(this, void 0, void 0, function* () {
71
- const TeXRepresentation = input.getValue();
72
- const SVGRepresentation = yield (0, transform_1.convertTeXToSVG)(TeXRepresentation, true);
73
- if (!SVGRepresentation) {
74
- throw new Error('No SVG output from MathJax');
75
- }
70
+ const contents = input.getValue();
76
71
  const pos = this.getPos();
77
72
  const { tr } = this.view.state;
78
- tr.setNodeMarkup(pos, undefined, Object.assign(Object.assign({}, this.node.attrs), { TeXRepresentation,
79
- SVGRepresentation })).setSelection(prosemirror_state_1.NodeSelection.create(tr.doc, pos));
73
+ const format = contents.includes('mml:math') ? 'mathml' : 'tex';
74
+ tr.setNodeMarkup(pos, undefined, Object.assign(Object.assign({}, this.node.attrs), { format,
75
+ contents })).setSelection(prosemirror_state_1.NodeSelection.create(tr.doc, pos));
80
76
  this.view.dispatch(tr);
81
77
  }));
82
78
  this.props.popper.show(this.dom, input.getWrapperElement(), 'bottom');
@@ -16,6 +16,7 @@
16
16
  */
17
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
18
  exports.InlineFootnoteView = void 0;
19
+ const track_changes_utils_1 = require("../lib/track-changes-utils");
19
20
  const base_node_view_1 = require("./base_node_view");
20
21
  const creators_1 = require("./creators");
21
22
  class InlineFootnoteView extends base_node_view_1.BaseNodeView {
@@ -26,6 +27,10 @@ class InlineFootnoteView extends base_node_view_1.BaseNodeView {
26
27
  };
27
28
  this.updateContents = () => {
28
29
  this.setDomAttrs(this.node, this.dom);
30
+ this.dom.className = [
31
+ 'footnote',
32
+ ...(0, track_changes_utils_1.getChangeClasses)(this.node.attrs.dataTracked),
33
+ ].join(' ');
29
34
  };
30
35
  this.initialise = () => {
31
36
  this.dom = this.createDOM();
@@ -15,7 +15,7 @@
15
15
  */
16
16
  import { ObjectTypes } from '@manuscripts/json-schema';
17
17
  import { skipTracking } from '@manuscripts/track-changes-plugin';
18
- import { buildComment, buildInlineMathFragment, generateID, isElementNodeType, isInBibliographySection, isListNode, isSectionNodeType, schema, } from '@manuscripts/transform';
18
+ import { buildComment, generateID, isElementNodeType, isInBibliographySection, isListNode, isSectionNodeType, schema, } from '@manuscripts/transform';
19
19
  import { NodeRange } from 'prosemirror-model';
20
20
  import { wrapInList } from 'prosemirror-schema-list';
21
21
  import { NodeSelection, TextSelection, } from 'prosemirror-state';
@@ -23,6 +23,7 @@ import { findWrapping } from 'prosemirror-transform';
23
23
  import { findChildrenByType, findParentNodeOfType, } from 'prosemirror-utils';
24
24
  import { skipCommandTracking } from './keys/list';
25
25
  import { isNodeOfType, nearestAncestor } from './lib/helpers';
26
+ import { isDeleted, isRejectedInsert } from './lib/track-changes-utils';
26
27
  import { findParentNodeWithId, getChildOfType } from './lib/utils';
27
28
  import { commentAnnotation } from './plugins/comment_annotation';
28
29
  import { highlightKey, SET_COMMENT } from './plugins/highlight';
@@ -101,7 +102,6 @@ export const createBlock = (nodeType, position, state, dispatch) => {
101
102
  case state.schema.nodes.equation_element:
102
103
  node = state.schema.nodes.equation_element.create({}, [
103
104
  state.schema.nodes.equation.create(),
104
- createAndFillFigcaptionElement(state),
105
105
  ]);
106
106
  break;
107
107
  default:
@@ -272,10 +272,10 @@ export const insertCrossReference = (state, dispatch) => {
272
272
  return true;
273
273
  };
274
274
  export const insertInlineEquation = (state, dispatch) => {
275
- const inlineMathFragment = buildInlineMathFragment(state.selection.$anchor.parent.attrs.id, selectedText().replace(/^\$/, '').replace(/\$$/, ''));
276
275
  const sourcePos = state.selection.from - 1;
277
276
  const tr = state.tr.replaceSelectionWith(state.schema.nodes.inline_equation.create({
278
- id: inlineMathFragment._id,
277
+ format: 'tex',
278
+ contents: selectedText().replace(/^\$/, '').replace(/\$$/, ''),
279
279
  }));
280
280
  if (dispatch) {
281
281
  const selection = NodeSelection.create(tr.doc, tr.mapping.map(sourcePos) + 1);
@@ -701,10 +701,12 @@ export const insertTableFootnote = (node, position, state, dispatch) => {
701
701
  const tr = state.tr;
702
702
  tr.insert(insertedAt, inlineFootnoteNode);
703
703
  let insertionPos;
704
- const footnotesElement = findChildrenByType(node, schema.nodes.footnotes_element);
705
- if (footnotesElement.length) {
706
- const pos = footnotesElement[0].pos;
707
- insertionPos = position + pos + footnotesElement[0].node.nodeSize + 1;
704
+ const footnotesElement = findChildrenByType(node, schema.nodes.footnotes_element).pop();
705
+ if (footnotesElement &&
706
+ !isDeleted(footnotesElement.node) &&
707
+ !isRejectedInsert(footnotesElement.node)) {
708
+ const pos = footnotesElement.pos;
709
+ insertionPos = position + pos + footnotesElement.node.nodeSize + 1;
708
710
  tr.insert(insertionPos, footnote);
709
711
  }
710
712
  else {
@@ -19,6 +19,7 @@ import { findChildrenByType, hasParentNodeOfType } from 'prosemirror-utils';
19
19
  import { addComment, createBlock, insertGeneralFootnote, insertTableFootnote, } from '../commands';
20
20
  import ReactSubView from '../views/ReactSubView';
21
21
  import { PopperManager } from './popper';
22
+ import { isDeleted, isRejectedInsert } from './track-changes-utils';
22
23
  const popper = new PopperManager();
23
24
  const listTypes = [schema.nodes.ordered_list, schema.nodes.bullet_list];
24
25
  const readonlyTypes = [schema.nodes.keywords, schema.nodes.bibliography_element];
@@ -179,14 +180,16 @@ export class ContextMenu {
179
180
  if (isInTable) {
180
181
  menu.appendChild(this.createMenuSection((section) => {
181
182
  section.appendChild(this.createMenuItem('Add Reference Note', () => {
182
- var _a;
183
- const footnotesElement = findChildrenByType(this.node, schema.nodes.footnotes_element);
184
- if (!footnotesElement.length) {
183
+ var _a, _b;
184
+ const footnotesElement = (_a = findChildrenByType(this.node, schema.nodes.footnotes_element).pop()) === null || _a === void 0 ? void 0 : _a.node;
185
+ if (!footnotesElement ||
186
+ isDeleted(footnotesElement) ||
187
+ isRejectedInsert(footnotesElement)) {
185
188
  const { state, dispatch } = this.view;
186
189
  insertTableFootnote(this.node, this.getPos(), state, dispatch);
187
190
  }
188
191
  else {
189
- const footnotes = findChildrenByType(footnotesElement[0].node, schema.nodes.footnote).map((nodeWithPos) => {
192
+ const footnotes = findChildrenByType(footnotesElement, schema.nodes.footnote).map((nodeWithPos) => {
190
193
  return nodeWithPos.node;
191
194
  });
192
195
  const targetDom = this.view.domAtPos(this.view.state.selection.from);
@@ -218,7 +221,7 @@ export class ContextMenu {
218
221
  (_a = this.props) === null || _a === void 0 ? void 0 : _a.popper.destroy();
219
222
  },
220
223
  }, this.node, this.getPos, this.view, 'table-footnote-editor');
221
- (_a = this.props) === null || _a === void 0 ? void 0 : _a.popper.show(targetDom.node, popperContainer, 'bottom-end');
224
+ (_b = this.props) === null || _b === void 0 ? void 0 : _b.popper.show(targetDom.node, popperContainer, 'bottom-end');
222
225
  }
223
226
  }
224
227
  }));
@@ -13,6 +13,15 @@
13
13
  * See the License for the specific language governing permissions and
14
14
  * limitations under the License.
15
15
  */
16
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
17
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
18
+ return new (P || (P = Promise))(function (resolve, reject) {
19
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
20
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
21
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
22
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
23
+ });
24
+ };
16
25
  export const isNodeOfType = (...type) => (node) => {
17
26
  const [head, ...tail] = type;
18
27
  if (node.type === node.type.schema.nodes[head]) {
@@ -44,3 +53,13 @@ export const mergeSimilarItems = (compareFunc, mergeFunc) => (items) => {
44
53
  ];
45
54
  }, []);
46
55
  };
56
+ export const renderMath = (math, format) => __awaiter(void 0, void 0, void 0, function* () {
57
+ if (format === 'tex') {
58
+ const { convertTeXToSVG } = yield import('../lib/tex-to-svg');
59
+ return convertTeXToSVG(math);
60
+ }
61
+ else {
62
+ const { convertMathMLToSVG } = yield import('../lib/mathml-to-svg');
63
+ return convertMathMLToSVG(math);
64
+ }
65
+ });
@@ -0,0 +1,66 @@
1
+ /*!
2
+ * © 2019 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 'mathjax-full/js/util/entities/all';
17
+ import { xmlSerializer } from '@manuscripts/transform';
18
+ import { HTMLAdaptor } from 'mathjax-full/js/adaptors/HTMLAdaptor';
19
+ import { MmlFactory } from 'mathjax-full/js/core/MmlTree/MmlFactory';
20
+ import { HTMLDocument } from 'mathjax-full/js/handlers/html/HTMLDocument';
21
+ import { MathML } from 'mathjax-full/js/input/mathml';
22
+ import { SVG } from 'mathjax-full/js/output/svg';
23
+ class ManuscriptsMmlFactory extends MmlFactory {
24
+ constructor() {
25
+ super();
26
+ this.nodeMap.set('image', this.nodeMap.get('none'));
27
+ }
28
+ create(kind, properties = {}, children = []) {
29
+ if (kind === 'image') {
30
+ return this.node['none'](properties, children);
31
+ }
32
+ return this.node[kind](properties, children);
33
+ }
34
+ }
35
+ class ManuscriptsHTMLAdaptor extends HTMLAdaptor {
36
+ setAttribute(node, name, value, ns) {
37
+ if (name !== 'xmlns') {
38
+ ns ? node.setAttributeNS(ns, name, value) : node.setAttribute(name, value);
39
+ }
40
+ }
41
+ }
42
+ const InputJax = new MathML();
43
+ const OutputJax = new SVG({
44
+ fontCache: 'none',
45
+ });
46
+ const adaptor = new ManuscriptsHTMLAdaptor(window);
47
+ const doc = new HTMLDocument(document, adaptor, {
48
+ InputJax,
49
+ OutputJax,
50
+ MmlFactory: new ManuscriptsMmlFactory(),
51
+ });
52
+ doc.addStyleSheet();
53
+ export const convertMathMLToSVG = (mathml, display = true) => {
54
+ const item = doc.convert(mathml, {
55
+ display,
56
+ em: 16,
57
+ ex: 8,
58
+ containerWidth: 1000000,
59
+ lineWidth: 1000000,
60
+ scale: 1,
61
+ });
62
+ if (!item || !item.firstChild) {
63
+ return null;
64
+ }
65
+ return xmlSerializer.serializeToString(item.firstChild);
66
+ };
@@ -0,0 +1,56 @@
1
+ /*!
2
+ * © 2019 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 'mathjax-full/js/util/entities/all';
17
+ import { xmlSerializer } from '@manuscripts/transform';
18
+ import { HTMLAdaptor } from 'mathjax-full/js/adaptors/HTMLAdaptor';
19
+ import { HTMLDocument } from 'mathjax-full/js/handlers/html/HTMLDocument';
20
+ import { TeX } from 'mathjax-full/js/input/tex';
21
+ import { AllPackages } from 'mathjax-full/js/input/tex/AllPackages';
22
+ import { SVG } from 'mathjax-full/js/output/svg';
23
+ export const packages = AllPackages.filter((name) => name !== 'html' && name !== 'bussproofs');
24
+ class ManuscriptsHTMLAdaptor extends HTMLAdaptor {
25
+ setAttribute(node, name, value, ns) {
26
+ if (name !== 'xmlns') {
27
+ ns ? node.setAttributeNS(ns, name, value) : node.setAttribute(name, value);
28
+ }
29
+ }
30
+ }
31
+ const InputJax = new TeX({
32
+ packages,
33
+ });
34
+ const OutputJax = new SVG({
35
+ fontCache: 'none',
36
+ });
37
+ const adaptor = new ManuscriptsHTMLAdaptor(window);
38
+ const doc = new HTMLDocument(document, adaptor, {
39
+ InputJax,
40
+ OutputJax,
41
+ });
42
+ doc.addStyleSheet();
43
+ export const convertTeXToSVG = (tex, display = true) => {
44
+ const item = doc.convert(tex, {
45
+ display,
46
+ em: 16,
47
+ ex: 8,
48
+ containerWidth: 1000000,
49
+ lineWidth: 1000000,
50
+ scale: 1,
51
+ });
52
+ if (!item || !item.firstChild) {
53
+ return null;
54
+ }
55
+ return xmlSerializer.serializeToString(item.firstChild);
56
+ };
@@ -127,9 +127,6 @@ export default () => {
127
127
  }
128
128
  }
129
129
  if (node.type === schema.nodes.footnotes_element) {
130
- decorations.push(Decoration.node(pos, pos + node.nodeSize, {
131
- class: 'footnote-element',
132
- }));
133
130
  if ((parent === null || parent === void 0 ? void 0 : parent.type) === schema.nodes.table_element_footer) {
134
131
  tableInlineFootnoteIds = findTableInlineFootnoteIds(state.doc.resolve(pos));
135
132
  }
@@ -14,6 +14,7 @@
14
14
  * limitations under the License.
15
15
  */
16
16
  import { sanitize } from '../lib/dompurify';
17
+ import { renderMath } from '../lib/helpers';
17
18
  import { BaseNodeView } from './base_node_view';
18
19
  import { createNodeView } from './creators';
19
20
  export class EquationView extends BaseNodeView {
@@ -29,22 +30,29 @@ export class EquationView extends BaseNodeView {
29
30
  this.dom.setAttribute('id', this.node.attrs.id);
30
31
  };
31
32
  this.updateContents = () => {
32
- const { SVGStringRepresentation } = this.node.attrs;
33
+ const { contents, format } = this.node.attrs;
33
34
  while (this.dom.hasChildNodes()) {
34
35
  this.dom.removeChild(this.dom.firstChild);
35
36
  }
36
- if (SVGStringRepresentation) {
37
- const fragment = sanitize(SVGStringRepresentation, {
38
- USE_PROFILES: { svg: true },
39
- });
40
- this.dom.appendChild(fragment);
41
- }
42
- else {
43
- const placeholder = document.createElement('div');
44
- placeholder.className = 'equation-placeholder';
45
- placeholder.textContent = '<Equation>';
46
- this.dom.appendChild(placeholder);
47
- }
37
+ renderMath(contents, format)
38
+ .then((svgContent) => {
39
+ if (svgContent) {
40
+ const fragment = sanitize(svgContent, {
41
+ USE_PROFILES: { svg: true },
42
+ });
43
+ this.dom.appendChild(fragment);
44
+ }
45
+ else {
46
+ const placeholder = document.createElement('div');
47
+ placeholder.className = 'equation-placeholder';
48
+ placeholder.textContent = '<Equation>';
49
+ this.dom.appendChild(placeholder);
50
+ }
51
+ return true;
52
+ })
53
+ .catch((error) => {
54
+ console.error(error);
55
+ });
48
56
  };
49
57
  this.ignoreMutation = () => true;
50
58
  }
@@ -22,7 +22,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
22
22
  step((generator = generator.apply(thisArg, _arguments || [])).next());
23
23
  });
24
24
  };
25
- import { convertTeXToSVG } from '@manuscripts/transform';
26
25
  import { NodeSelection } from 'prosemirror-state';
27
26
  import { createEditableNodeView } from './creators';
28
27
  import { EquationView } from './equation';
@@ -36,21 +35,18 @@ export class EquationEditableView extends EquationView {
36
35
  const { createEditor } = yield import('../lib/codemirror');
37
36
  const placeholder = 'Enter LaTeX equation, e.g. "a^2 = \\sqrt{b^2 + c^2}"';
38
37
  const input = yield createEditor({
39
- value: this.node.attrs.TeXRepresentation || '',
38
+ value: this.node.attrs.contents || '',
40
39
  mode: 'stex',
41
40
  placeholder,
42
41
  autofocus: true,
43
42
  });
44
43
  input.on('changes', () => __awaiter(this, void 0, void 0, function* () {
45
- const TeXRepresentation = input.getValue();
46
- const SVGStringRepresentation = yield convertTeXToSVG(TeXRepresentation, true);
47
- if (!SVGStringRepresentation) {
48
- throw new Error('No SVG output from MathJax');
49
- }
44
+ const contents = input.getValue();
50
45
  const pos = this.getPos();
51
46
  const { tr } = this.view.state;
52
- tr.setNodeMarkup(pos, undefined, Object.assign(Object.assign({}, this.node.attrs), { TeXRepresentation,
53
- SVGStringRepresentation })).setSelection(NodeSelection.create(tr.doc, pos));
47
+ const format = contents.includes('mml:math') ? 'mathml' : 'tex';
48
+ tr.setNodeMarkup(pos, undefined, Object.assign(Object.assign({}, this.node.attrs), { contents,
49
+ format })).setSelection(NodeSelection.create(tr.doc, pos));
54
50
  this.view.dispatch(tr);
55
51
  }));
56
52
  const wrapper = document.createElement('div');
@@ -21,9 +21,12 @@ export class EquationElementView extends BlockView {
21
21
  this.elementType = 'figure';
22
22
  this.updateContents = () => {
23
23
  var _a;
24
- const { suppressCaption, suppressTitle } = this.node.attrs;
25
- this.dom.classList.toggle('suppress-caption', suppressCaption);
26
- this.dom.classList.toggle('suppress-title', suppressTitle === undefined ? true : suppressTitle);
24
+ const { label } = this.node.attrs;
25
+ if (label) {
26
+ const labelEl = document.createElement('label');
27
+ labelEl.textContent = label;
28
+ this.dom.appendChild(labelEl);
29
+ }
27
30
  if ((_a = this.node.attrs.dataTracked) === null || _a === void 0 ? void 0 : _a.length) {
28
31
  const lastChange = this.node.attrs.dataTracked[this.node.attrs.dataTracked.length - 1];
29
32
  this.dom.setAttribute('data-track-status', lastChange.status);
@@ -13,21 +13,39 @@
13
13
  * See the License for the specific language governing permissions and
14
14
  * limitations under the License.
15
15
  */
16
+ import { schema } from '@manuscripts/transform';
17
+ import { getChangeClasses } from '../lib/track-changes-utils';
16
18
  import BlockView from './block_view';
17
- import { createNodeOrElementView } from './creators';
19
+ import { createNodeView } from './creators';
18
20
  export class FootnotesElementView extends BlockView {
19
21
  constructor() {
20
22
  super(...arguments);
21
23
  this.elementType = 'div';
24
+ this.updateContents = () => {
25
+ const $pos = this.view.state.doc.resolve(this.getPos());
26
+ if ($pos.parent.type === schema.nodes.table_element_footer) {
27
+ this.setTCClasses();
28
+ }
29
+ };
22
30
  this.checkEditability = () => {
23
31
  var _a, _b;
24
32
  const editable = this.node.childCount ? 'true' : 'false';
25
33
  (_a = this.contentDOM) === null || _a === void 0 ? void 0 : _a.setAttribute('contenteditable', editable);
26
34
  (_b = this.dom) === null || _b === void 0 ? void 0 : _b.setAttribute('contenteditable', editable);
27
35
  };
36
+ this.setTCClasses = () => {
37
+ const classNames = ['footnote-element'];
38
+ const dataTracked = this.node.attrs.dataTracked;
39
+ if (dataTracked === null || dataTracked === void 0 ? void 0 : dataTracked.length) {
40
+ const lastChange = dataTracked[dataTracked.length - 1];
41
+ const changeClasses = getChangeClasses([lastChange]);
42
+ classNames.push(...changeClasses);
43
+ }
44
+ this.dom.className = classNames.join(' ');
45
+ };
28
46
  }
29
47
  onUpdateContent() {
30
48
  this.checkEditability();
31
49
  }
32
50
  }
33
- export default createNodeOrElementView(FootnotesElementView, 'div');
51
+ export default createNodeView(FootnotesElementView);
@@ -13,7 +13,7 @@
13
13
  * See the License for the specific language governing permissions and
14
14
  * limitations under the License.
15
15
  */
16
- import { createNodeOrElementView } from './creators';
16
+ import { createNodeView } from './creators';
17
17
  import { EditableBlock } from './editable_block';
18
18
  import { FootnotesElementView } from './footnotes_element';
19
- export default createNodeOrElementView(EditableBlock(FootnotesElementView), 'div');
19
+ export default createNodeView(EditableBlock(FootnotesElementView));
@@ -14,6 +14,7 @@
14
14
  * limitations under the License.
15
15
  */
16
16
  import { sanitize } from '../lib/dompurify';
17
+ import { renderMath } from '../lib/helpers';
17
18
  import { isRejectedInsert } from '../lib/track-changes-utils';
18
19
  import { BaseNodeView } from './base_node_view';
19
20
  import { createNodeView } from './creators';
@@ -26,22 +27,29 @@ export class InlineEquationView extends BaseNodeView {
26
27
  };
27
28
  this.updateContents = () => {
28
29
  if (!isRejectedInsert(this.node)) {
29
- const { SVGRepresentation } = this.node.attrs;
30
+ const { contents, format } = this.node.attrs;
30
31
  while (this.dom.hasChildNodes()) {
31
32
  this.dom.removeChild(this.dom.firstChild);
32
33
  }
33
- if (SVGRepresentation) {
34
- const fragment = sanitize(SVGRepresentation, {
35
- USE_PROFILES: { svg: true },
36
- });
37
- this.dom.appendChild(fragment);
38
- }
39
- else {
40
- const placeholder = document.createElement('div');
41
- placeholder.className = 'equation-placeholder';
42
- placeholder.textContent = '<Equation>';
43
- this.dom.appendChild(placeholder);
44
- }
34
+ renderMath(contents, format)
35
+ .then((svgContent) => {
36
+ if (svgContent) {
37
+ const fragment = sanitize(svgContent, {
38
+ USE_PROFILES: { svg: true },
39
+ });
40
+ this.dom.appendChild(fragment);
41
+ }
42
+ else {
43
+ const placeholder = document.createElement('div');
44
+ placeholder.className = 'equation-placeholder';
45
+ placeholder.textContent = '<Equation>';
46
+ this.dom.appendChild(placeholder);
47
+ }
48
+ return true;
49
+ })
50
+ .catch((error) => {
51
+ console.error(error);
52
+ });
45
53
  }
46
54
  else {
47
55
  this.dom.innerHTML = '';
@@ -22,7 +22,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
22
22
  step((generator = generator.apply(thisArg, _arguments || [])).next());
23
23
  });
24
24
  };
25
- import { convertTeXToSVG } from '@manuscripts/transform';
26
25
  import { NodeSelection } from 'prosemirror-state';
27
26
  import { createEditableNodeView } from './creators';
28
27
  import { InlineEquationView } from './inline_equation';
@@ -36,21 +35,18 @@ export class InlineEquationEditableView extends InlineEquationView {
36
35
  const { createEditor } = yield import('../lib/codemirror');
37
36
  const placeholder = 'Enter LaTeX equation, e.g. "E=mc^2"';
38
37
  const input = yield createEditor({
39
- value: this.node.attrs.TeXRepresentation || '',
38
+ value: this.node.attrs.contents || '',
40
39
  mode: 'stex',
41
40
  placeholder,
42
41
  autofocus: true,
43
42
  });
44
43
  input.on('changes', () => __awaiter(this, void 0, void 0, function* () {
45
- const TeXRepresentation = input.getValue();
46
- const SVGRepresentation = yield convertTeXToSVG(TeXRepresentation, true);
47
- if (!SVGRepresentation) {
48
- throw new Error('No SVG output from MathJax');
49
- }
44
+ const contents = input.getValue();
50
45
  const pos = this.getPos();
51
46
  const { tr } = this.view.state;
52
- tr.setNodeMarkup(pos, undefined, Object.assign(Object.assign({}, this.node.attrs), { TeXRepresentation,
53
- SVGRepresentation })).setSelection(NodeSelection.create(tr.doc, pos));
47
+ const format = contents.includes('mml:math') ? 'mathml' : 'tex';
48
+ tr.setNodeMarkup(pos, undefined, Object.assign(Object.assign({}, this.node.attrs), { format,
49
+ contents })).setSelection(NodeSelection.create(tr.doc, pos));
54
50
  this.view.dispatch(tr);
55
51
  }));
56
52
  this.props.popper.show(this.dom, input.getWrapperElement(), 'bottom');
@@ -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 { getChangeClasses } from '../lib/track-changes-utils';
16
17
  import { BaseNodeView } from './base_node_view';
17
18
  import { createNodeView } from './creators';
18
19
  export class InlineFootnoteView extends BaseNodeView {
@@ -23,6 +24,10 @@ export class InlineFootnoteView extends BaseNodeView {
23
24
  };
24
25
  this.updateContents = () => {
25
26
  this.setDomAttrs(this.node, this.dom);
27
+ this.dom.className = [
28
+ 'footnote',
29
+ ...getChangeClasses(this.node.attrs.dataTracked),
30
+ ].join(' ');
26
31
  };
27
32
  this.initialise = () => {
28
33
  this.dom = this.createDOM();
@@ -18,3 +18,4 @@ import { Node, ResolvedPos } from 'prosemirror-model';
18
18
  export declare const isNodeOfType: (...type: string[]) => (node: Node) => boolean;
19
19
  export declare const nearestAncestor: (func: (node: ManuscriptNode) => boolean) => ($pos: ResolvedPos) => number | null;
20
20
  export declare const mergeSimilarItems: <T>(compareFunc: (a: T, b: T) => boolean, mergeFunc: (a: T, b: T) => T) => (items: T[]) => T[];
21
+ export declare const renderMath: (math: string, format: string) => Promise<string | null>;
@@ -0,0 +1,17 @@
1
+ /*!
2
+ * © 2019 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 'mathjax-full/js/util/entities/all';
17
+ export declare const convertMathMLToSVG: (mathml: string, display?: boolean) => string | null;
@@ -0,0 +1,18 @@
1
+ /*!
2
+ * © 2019 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 'mathjax-full/js/util/entities/all';
17
+ export declare const packages: string[];
18
+ export declare const convertTeXToSVG: (tex: string, display?: boolean) => string | null;
@@ -17,8 +17,10 @@ import { BaseNodeProps } from './base_node_view';
17
17
  import BlockView from './block_view';
18
18
  export declare class FootnotesElementView<PropsType extends BaseNodeProps> extends BlockView<PropsType> {
19
19
  elementType: string;
20
+ updateContents: () => void;
20
21
  onUpdateContent(): void;
21
22
  checkEditability: () => void;
23
+ setTCClasses: () => void;
22
24
  }
23
- declare const _default: (props: BaseNodeProps) => import("../types").NodeViewCreator<FootnotesElementView<any>>;
25
+ declare const _default: (props: BaseNodeProps, dispatch?: import("..").Dispatch | undefined) => import("../types").NodeViewCreator<FootnotesElementView<any>>;
24
26
  export default _default;
@@ -14,7 +14,7 @@
14
14
  * limitations under the License.
15
15
  */
16
16
  import { FootnotesElementView } from './footnotes_element';
17
- declare const _default: (props: import("./base_node_view").BaseNodeProps) => import("../types").NodeViewCreator<{
17
+ declare const _default: (props: import("./base_node_view").BaseNodeProps, dispatch?: import("..").Dispatch | undefined) => import("../types").NodeViewCreator<{
18
18
  gutterButtons: () => HTMLElement[];
19
19
  actionGutterButtons: () => HTMLElement[];
20
20
  createSyncWarningButton: () => HTMLElement | null;
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.15",
4
+ "version": "1.7.16-LEAN-3405-0",
5
5
  "repository": "github:Atypon-OpenSource/manuscripts-body-editor",
6
6
  "license": "Apache-2.0",
7
7
  "main": "dist/cjs",
@@ -29,13 +29,14 @@
29
29
  "dependencies": {
30
30
  "@iarna/word-count": "^1.1.2",
31
31
  "@manuscripts/assets": "^0.6.4",
32
- "@manuscripts/json-schema": "^2.2.4",
33
- "@manuscripts/library": "^1.3.3",
34
- "@manuscripts/style-guide": "^1.7.9",
32
+ "@manuscripts/json-schema": "^2.2.5",
33
+ "@manuscripts/library": "^1.3.4",
34
+ "@manuscripts/style-guide": "^1.7.10",
35
35
  "@manuscripts/track-changes-plugin": "^1.7.6",
36
- "@manuscripts/transform": "^2.1.4",
36
+ "@manuscripts/transform": "^2.1.5",
37
37
  "astrocite-eutils": "^0.16.4",
38
38
  "axios": "^1.6.7",
39
+ "mathjax-full": "^3.2.2",
39
40
  "codemirror": "^5.58.1",
40
41
  "dompurify": "^2.4.1",
41
42
  "grapheme-splitter": "^1.0.4",
package/styles/Editor.css CHANGED
@@ -944,6 +944,11 @@
944
944
  padding-top: 8px;
945
945
  }
946
946
 
947
+ .ProseMirror .table-footer .block-gutter,
948
+ .ProseMirror .table-footer .action-gutter {
949
+ display: none;
950
+ }
951
+
947
952
  .ProseMirror .table-footer .footnote-element:not(:first-child)::before {
948
953
  content: '';
949
954
  border-bottom: 1px dashed #C9C9C9;
@@ -955,7 +960,12 @@
955
960
  counter-reset: table_footnote;
956
961
  }
957
962
 
958
- .ProseMirror .table-footer .footnote-element > div:not(:has(.unctied-table-footnote)) p::before {
963
+ .ProseMirror
964
+ .table-footer
965
+ .footnote-element
966
+ div.block
967
+ > div:not(:has(.unctied-table-footnote))
968
+ p::before {
959
969
  counter-increment: table_footnote;
960
970
  content: counter(table_footnote);
961
971
  display: inline-block;
@@ -998,7 +1008,7 @@
998
1008
  cursor: pointer;
999
1009
  }
1000
1010
 
1001
- .ProseMirror .footnote-element > div:has(.unctied-table-footnote) {
1011
+ .ProseMirror .footnote-element div.block > div:has(.unctied-table-footnote) {
1002
1012
  position: relative;
1003
1013
  }
1004
1014