@manuscripts/body-editor 2.0.6 → 2.0.7-LEAN-3724.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.
- package/dist/cjs/commands.js +79 -2
- package/dist/cjs/components/views/TableCellContextMenu.js +11 -4
- package/dist/cjs/versions.js +1 -1
- package/dist/es/commands.js +78 -2
- package/dist/es/components/views/TableCellContextMenu.js +13 -6
- package/dist/es/versions.js +1 -1
- package/dist/types/commands.d.ts +1 -0
- package/dist/types/versions.d.ts +1 -1
- package/package.json +1 -1
package/dist/cjs/commands.js
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* limitations under the License.
|
|
16
16
|
*/
|
|
17
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
-
exports.addColumns = exports.addRows = exports.insertTableFootnote = exports.addInlineComment = exports.addNodeComment = exports.createAndFillTableElement = exports.selectAllIsolating = exports.ignoreAtomBlockNodeForward = exports.isAtEndOfTextBlock = exports.ignoreMetaNodeBackspaceCommand = exports.ignoreAtomBlockNodeBackward = exports.isTextSelection = exports.isAtStartOfTextBlock = exports.insertTOCSection = exports.insertBibliographySection = exports.insertList = exports.insertKeywords = exports.insertContributors = exports.insertAbstract = exports.insertBackMatterSection = exports.insertSection = exports.insertGraphicalAbstract = exports.insertInlineFootnote = exports.insertFootnote = exports.createFootnote = exports.insertInlineEquation = exports.insertCrossReference = exports.insertInlineCitation = exports.insertLink = exports.insertSectionLabel = exports.insertBreak = exports.deleteBlock = exports.insertBlock = exports.insertSupplement = exports.insertFigure = exports.insertGeneralFootnote = exports.createBlock = exports.createSelection = exports.canInsert = exports.blockActive = exports.isNodeSelection = exports.markActive = void 0;
|
|
18
|
+
exports.mergeCellsWithSpace = exports.addColumns = exports.addRows = exports.insertTableFootnote = exports.addInlineComment = exports.addNodeComment = exports.createAndFillTableElement = exports.selectAllIsolating = exports.ignoreAtomBlockNodeForward = exports.isAtEndOfTextBlock = exports.ignoreMetaNodeBackspaceCommand = exports.ignoreAtomBlockNodeBackward = exports.isTextSelection = exports.isAtStartOfTextBlock = exports.insertTOCSection = exports.insertBibliographySection = exports.insertList = exports.insertKeywords = exports.insertContributors = exports.insertAbstract = exports.insertBackMatterSection = exports.insertSection = exports.insertGraphicalAbstract = exports.insertInlineFootnote = exports.insertFootnote = exports.createFootnote = exports.insertInlineEquation = exports.insertCrossReference = exports.insertInlineCitation = exports.insertLink = exports.insertSectionLabel = exports.insertBreak = exports.deleteBlock = exports.insertBlock = exports.insertSupplement = exports.insertFigure = exports.insertGeneralFootnote = exports.createBlock = exports.createSelection = exports.canInsert = exports.blockActive = exports.isNodeSelection = exports.markActive = void 0;
|
|
19
19
|
const json_schema_1 = require("@manuscripts/json-schema");
|
|
20
20
|
const track_changes_plugin_1 = require("@manuscripts/track-changes-plugin");
|
|
21
21
|
const transform_1 = require("@manuscripts/transform");
|
|
@@ -787,7 +787,7 @@ const createAndFillTableElement = (state, tableConfig) => {
|
|
|
787
787
|
const { nodes } = state.schema;
|
|
788
788
|
const { numberOfColumns, numberOfRows, includeHeader } = tableConfig;
|
|
789
789
|
const createRow = (cellType) => {
|
|
790
|
-
const cells = Array.from({ length: numberOfColumns }, () => nodes[cellType].create());
|
|
790
|
+
const cells = Array.from({ length: numberOfColumns }, () => nodes[cellType].create({}, state.schema.nodes.paragraph.create()));
|
|
791
791
|
return nodes.table_row.create({}, cells);
|
|
792
792
|
};
|
|
793
793
|
const tableRows = includeHeader ? [createRow('table_header')] : [];
|
|
@@ -1012,3 +1012,80 @@ const addColumns = (direction) => (state, dispatch) => {
|
|
|
1012
1012
|
return true;
|
|
1013
1013
|
};
|
|
1014
1014
|
exports.addColumns = addColumns;
|
|
1015
|
+
function isEmpty(cell) {
|
|
1016
|
+
const c = cell.content;
|
|
1017
|
+
return (c.childCount == 1 && c.child(0).isTextblock && c.child(0).childCount == 0);
|
|
1018
|
+
}
|
|
1019
|
+
function cellsOverlapRectangle({ width, height, map }, rect) {
|
|
1020
|
+
let indexTop = rect.top * width + rect.left, indexLeft = indexTop;
|
|
1021
|
+
let indexBottom = (rect.bottom - 1) * width + rect.left, indexRight = indexTop + (rect.right - rect.left - 1);
|
|
1022
|
+
for (let i = rect.top; i < rect.bottom; i++) {
|
|
1023
|
+
if ((rect.left > 0 && map[indexLeft] == map[indexLeft - 1]) ||
|
|
1024
|
+
(rect.right < width && map[indexRight] == map[indexRight + 1])) {
|
|
1025
|
+
return true;
|
|
1026
|
+
}
|
|
1027
|
+
indexLeft += width;
|
|
1028
|
+
indexRight += width;
|
|
1029
|
+
}
|
|
1030
|
+
for (let i = rect.left; i < rect.right; i++) {
|
|
1031
|
+
if ((rect.top > 0 && map[indexTop] == map[indexTop - width]) ||
|
|
1032
|
+
(rect.bottom < height && map[indexBottom] == map[indexBottom + width])) {
|
|
1033
|
+
return true;
|
|
1034
|
+
}
|
|
1035
|
+
indexTop++;
|
|
1036
|
+
indexBottom++;
|
|
1037
|
+
}
|
|
1038
|
+
return false;
|
|
1039
|
+
}
|
|
1040
|
+
function mergeCellsWithSpace(state, dispatch) {
|
|
1041
|
+
const sel = state.selection;
|
|
1042
|
+
if (!(sel instanceof prosemirror_tables_1.CellSelection) ||
|
|
1043
|
+
sel.$anchorCell.pos == sel.$headCell.pos) {
|
|
1044
|
+
return false;
|
|
1045
|
+
}
|
|
1046
|
+
const rect = (0, prosemirror_tables_1.selectedRect)(state), { map } = rect;
|
|
1047
|
+
if (cellsOverlapRectangle(map, rect)) {
|
|
1048
|
+
return false;
|
|
1049
|
+
}
|
|
1050
|
+
if (dispatch) {
|
|
1051
|
+
const tr = state.tr;
|
|
1052
|
+
const seen = {};
|
|
1053
|
+
let content = prosemirror_model_1.Fragment.empty;
|
|
1054
|
+
let mergedPos;
|
|
1055
|
+
let mergedCell;
|
|
1056
|
+
for (let row = rect.top; row < rect.bottom; row++) {
|
|
1057
|
+
for (let col = rect.left; col < rect.right; col++) {
|
|
1058
|
+
const cellPos = map.map[row * map.width + col];
|
|
1059
|
+
const cell = rect.table.nodeAt(cellPos);
|
|
1060
|
+
if (seen[cellPos] || !cell) {
|
|
1061
|
+
continue;
|
|
1062
|
+
}
|
|
1063
|
+
seen[cellPos] = true;
|
|
1064
|
+
if (mergedPos == null) {
|
|
1065
|
+
mergedPos = cellPos;
|
|
1066
|
+
mergedCell = cell;
|
|
1067
|
+
}
|
|
1068
|
+
else {
|
|
1069
|
+
if (!isEmpty(cell)) {
|
|
1070
|
+
content = content.append(cell.content.addToStart(cell.type.schema.text(' ')));
|
|
1071
|
+
}
|
|
1072
|
+
const mapped = tr.mapping.map(cellPos + rect.tableStart);
|
|
1073
|
+
tr.delete(mapped, mapped + cell.nodeSize);
|
|
1074
|
+
}
|
|
1075
|
+
}
|
|
1076
|
+
}
|
|
1077
|
+
if (mergedPos == null || mergedCell == null) {
|
|
1078
|
+
return true;
|
|
1079
|
+
}
|
|
1080
|
+
tr.setNodeMarkup(mergedPos + rect.tableStart, null, Object.assign(Object.assign({}, (0, prosemirror_tables_1.addColSpan)(mergedCell.attrs, mergedCell.attrs.colspan, rect.right - rect.left - mergedCell.attrs.colspan)), { rowspan: rect.bottom - rect.top }));
|
|
1081
|
+
if (content.size) {
|
|
1082
|
+
const end = mergedPos + 1 + mergedCell.content.size;
|
|
1083
|
+
const start = isEmpty(mergedCell) ? mergedPos + 1 : end;
|
|
1084
|
+
tr.replaceWith(start + rect.tableStart, end + rect.tableStart, content);
|
|
1085
|
+
}
|
|
1086
|
+
tr.setSelection(new prosemirror_tables_1.CellSelection(tr.doc.resolve(mergedPos + rect.tableStart)));
|
|
1087
|
+
dispatch(tr);
|
|
1088
|
+
}
|
|
1089
|
+
return true;
|
|
1090
|
+
}
|
|
1091
|
+
exports.mergeCellsWithSpace = mergeCellsWithSpace;
|
|
@@ -53,16 +53,20 @@ const ContextMenu = ({ view, close, }) => {
|
|
|
53
53
|
close();
|
|
54
54
|
};
|
|
55
55
|
const [columnAction, setColumnAction] = (0, react_1.useState)(undefined);
|
|
56
|
+
const isCellSelectionMerged = (0, prosemirror_tables_1.mergeCells)(view.state);
|
|
57
|
+
const isCellSelectionSplittable = (0, prosemirror_tables_1.splitCell)(view.state);
|
|
56
58
|
const { rows, columns } = getSelectedCellsCount(view.state);
|
|
57
59
|
return (react_1.default.createElement(MenuDropdownList, null,
|
|
58
60
|
react_1.default.createElement(ActionButton, { onClick: () => runCommand((0, commands_1.addRows)('top')) },
|
|
59
61
|
react_1.default.createElement(style_guide_1.PlusIcon, null),
|
|
60
|
-
" Insert
|
|
61
|
-
rows
|
|
62
|
+
" Insert ",
|
|
63
|
+
rows,
|
|
64
|
+
" above"),
|
|
62
65
|
react_1.default.createElement(ActionButton, { onClick: () => runCommand((0, commands_1.addRows)('bottom')) },
|
|
63
66
|
react_1.default.createElement(style_guide_1.PlusIcon, null),
|
|
64
|
-
" Insert
|
|
65
|
-
rows
|
|
67
|
+
" Insert ",
|
|
68
|
+
rows,
|
|
69
|
+
" below"),
|
|
66
70
|
react_1.default.createElement(ActionButton, { onClick: () => setColumnAction(() => (0, commands_1.addColumns)('left')) },
|
|
67
71
|
react_1.default.createElement(style_guide_1.PlusIcon, null),
|
|
68
72
|
" Insert ",
|
|
@@ -82,6 +86,9 @@ const ContextMenu = ({ view, close, }) => {
|
|
|
82
86
|
react_1.default.createElement(GrayDeleteIcon, null),
|
|
83
87
|
" Delete ",
|
|
84
88
|
columns),
|
|
89
|
+
(isCellSelectionMerged || isCellSelectionSplittable) && react_1.default.createElement(Separator, null),
|
|
90
|
+
isCellSelectionMerged && (react_1.default.createElement(ActionButton, { onClick: () => runCommand(commands_1.mergeCellsWithSpace, true) }, "Merge cells")),
|
|
91
|
+
isCellSelectionSplittable && (react_1.default.createElement(ActionButton, { onClick: () => runCommand(prosemirror_tables_1.splitCell, true) }, "Split cells")),
|
|
85
92
|
react_1.default.createElement(style_guide_1.ColumnChangeWarningDialog, { isOpen: !!columnAction, primaryAction: () => {
|
|
86
93
|
if (columnAction) {
|
|
87
94
|
runCommand(columnAction, true);
|
package/dist/cjs/versions.js
CHANGED
package/dist/es/commands.js
CHANGED
|
@@ -19,7 +19,7 @@ import { generateID, generateNodeID, isElementNodeType, isFootnoteNode, isInBibl
|
|
|
19
19
|
import { Fragment, NodeRange, } from 'prosemirror-model';
|
|
20
20
|
import { wrapInList } from 'prosemirror-schema-list';
|
|
21
21
|
import { NodeSelection, TextSelection, } from 'prosemirror-state';
|
|
22
|
-
import { addColumnAfter, addColumnBefore, addRow, selectedRect, } from 'prosemirror-tables';
|
|
22
|
+
import { addColSpan, addColumnAfter, addColumnBefore, addRow, CellSelection, selectedRect, } from 'prosemirror-tables';
|
|
23
23
|
import { findWrapping, liftTarget, ReplaceAroundStep, } from 'prosemirror-transform';
|
|
24
24
|
import { findChildrenByType, findParentNodeOfType, findParentNodeOfTypeClosestToPos, } from 'prosemirror-utils';
|
|
25
25
|
import { getCommentKey, getCommentRange } from './lib/comments';
|
|
@@ -748,7 +748,7 @@ export const createAndFillTableElement = (state, tableConfig) => {
|
|
|
748
748
|
const { nodes } = state.schema;
|
|
749
749
|
const { numberOfColumns, numberOfRows, includeHeader } = tableConfig;
|
|
750
750
|
const createRow = (cellType) => {
|
|
751
|
-
const cells = Array.from({ length: numberOfColumns }, () => nodes[cellType].create());
|
|
751
|
+
const cells = Array.from({ length: numberOfColumns }, () => nodes[cellType].create({}, state.schema.nodes.paragraph.create()));
|
|
752
752
|
return nodes.table_row.create({}, cells);
|
|
753
753
|
};
|
|
754
754
|
const tableRows = includeHeader ? [createRow('table_header')] : [];
|
|
@@ -967,3 +967,79 @@ export const addColumns = (direction) => (state, dispatch) => {
|
|
|
967
967
|
}
|
|
968
968
|
return true;
|
|
969
969
|
};
|
|
970
|
+
function isEmpty(cell) {
|
|
971
|
+
const c = cell.content;
|
|
972
|
+
return (c.childCount == 1 && c.child(0).isTextblock && c.child(0).childCount == 0);
|
|
973
|
+
}
|
|
974
|
+
function cellsOverlapRectangle({ width, height, map }, rect) {
|
|
975
|
+
let indexTop = rect.top * width + rect.left, indexLeft = indexTop;
|
|
976
|
+
let indexBottom = (rect.bottom - 1) * width + rect.left, indexRight = indexTop + (rect.right - rect.left - 1);
|
|
977
|
+
for (let i = rect.top; i < rect.bottom; i++) {
|
|
978
|
+
if ((rect.left > 0 && map[indexLeft] == map[indexLeft - 1]) ||
|
|
979
|
+
(rect.right < width && map[indexRight] == map[indexRight + 1])) {
|
|
980
|
+
return true;
|
|
981
|
+
}
|
|
982
|
+
indexLeft += width;
|
|
983
|
+
indexRight += width;
|
|
984
|
+
}
|
|
985
|
+
for (let i = rect.left; i < rect.right; i++) {
|
|
986
|
+
if ((rect.top > 0 && map[indexTop] == map[indexTop - width]) ||
|
|
987
|
+
(rect.bottom < height && map[indexBottom] == map[indexBottom + width])) {
|
|
988
|
+
return true;
|
|
989
|
+
}
|
|
990
|
+
indexTop++;
|
|
991
|
+
indexBottom++;
|
|
992
|
+
}
|
|
993
|
+
return false;
|
|
994
|
+
}
|
|
995
|
+
export function mergeCellsWithSpace(state, dispatch) {
|
|
996
|
+
const sel = state.selection;
|
|
997
|
+
if (!(sel instanceof CellSelection) ||
|
|
998
|
+
sel.$anchorCell.pos == sel.$headCell.pos) {
|
|
999
|
+
return false;
|
|
1000
|
+
}
|
|
1001
|
+
const rect = selectedRect(state), { map } = rect;
|
|
1002
|
+
if (cellsOverlapRectangle(map, rect)) {
|
|
1003
|
+
return false;
|
|
1004
|
+
}
|
|
1005
|
+
if (dispatch) {
|
|
1006
|
+
const tr = state.tr;
|
|
1007
|
+
const seen = {};
|
|
1008
|
+
let content = Fragment.empty;
|
|
1009
|
+
let mergedPos;
|
|
1010
|
+
let mergedCell;
|
|
1011
|
+
for (let row = rect.top; row < rect.bottom; row++) {
|
|
1012
|
+
for (let col = rect.left; col < rect.right; col++) {
|
|
1013
|
+
const cellPos = map.map[row * map.width + col];
|
|
1014
|
+
const cell = rect.table.nodeAt(cellPos);
|
|
1015
|
+
if (seen[cellPos] || !cell) {
|
|
1016
|
+
continue;
|
|
1017
|
+
}
|
|
1018
|
+
seen[cellPos] = true;
|
|
1019
|
+
if (mergedPos == null) {
|
|
1020
|
+
mergedPos = cellPos;
|
|
1021
|
+
mergedCell = cell;
|
|
1022
|
+
}
|
|
1023
|
+
else {
|
|
1024
|
+
if (!isEmpty(cell)) {
|
|
1025
|
+
content = content.append(cell.content.addToStart(cell.type.schema.text(' ')));
|
|
1026
|
+
}
|
|
1027
|
+
const mapped = tr.mapping.map(cellPos + rect.tableStart);
|
|
1028
|
+
tr.delete(mapped, mapped + cell.nodeSize);
|
|
1029
|
+
}
|
|
1030
|
+
}
|
|
1031
|
+
}
|
|
1032
|
+
if (mergedPos == null || mergedCell == null) {
|
|
1033
|
+
return true;
|
|
1034
|
+
}
|
|
1035
|
+
tr.setNodeMarkup(mergedPos + rect.tableStart, null, Object.assign(Object.assign({}, addColSpan(mergedCell.attrs, mergedCell.attrs.colspan, rect.right - rect.left - mergedCell.attrs.colspan)), { rowspan: rect.bottom - rect.top }));
|
|
1036
|
+
if (content.size) {
|
|
1037
|
+
const end = mergedPos + 1 + mergedCell.content.size;
|
|
1038
|
+
const start = isEmpty(mergedCell) ? mergedPos + 1 : end;
|
|
1039
|
+
tr.replaceWith(start + rect.tableStart, end + rect.tableStart, content);
|
|
1040
|
+
}
|
|
1041
|
+
tr.setSelection(new CellSelection(tr.doc.resolve(mergedPos + rect.tableStart)));
|
|
1042
|
+
dispatch(tr);
|
|
1043
|
+
}
|
|
1044
|
+
return true;
|
|
1045
|
+
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { ColumnChangeWarningDialog, DeleteIcon, IconTextButton, PlusIcon, } from '@manuscripts/style-guide';
|
|
2
2
|
import { skipTracking } from '@manuscripts/track-changes-plugin';
|
|
3
|
-
import { CellSelection, deleteColumn, deleteRow, selectedRect, } from 'prosemirror-tables';
|
|
3
|
+
import { CellSelection, deleteColumn, deleteRow, mergeCells, selectedRect, splitCell, } from 'prosemirror-tables';
|
|
4
4
|
import React, { useState } from 'react';
|
|
5
5
|
import styled from 'styled-components';
|
|
6
|
-
import { addColumns, addRows } from '../../commands';
|
|
6
|
+
import { addColumns, addRows, mergeCellsWithSpace } from '../../commands';
|
|
7
7
|
const getSelectedCellsCount = (state) => {
|
|
8
8
|
const { selection } = state;
|
|
9
9
|
const selectedCells = { rows: 1, columns: 1 };
|
|
@@ -24,16 +24,20 @@ export const ContextMenu = ({ view, close, }) => {
|
|
|
24
24
|
close();
|
|
25
25
|
};
|
|
26
26
|
const [columnAction, setColumnAction] = useState(undefined);
|
|
27
|
+
const isCellSelectionMerged = mergeCells(view.state);
|
|
28
|
+
const isCellSelectionSplittable = splitCell(view.state);
|
|
27
29
|
const { rows, columns } = getSelectedCellsCount(view.state);
|
|
28
30
|
return (React.createElement(MenuDropdownList, null,
|
|
29
31
|
React.createElement(ActionButton, { onClick: () => runCommand(addRows('top')) },
|
|
30
32
|
React.createElement(PlusIcon, null),
|
|
31
|
-
" Insert
|
|
32
|
-
rows
|
|
33
|
+
" Insert ",
|
|
34
|
+
rows,
|
|
35
|
+
" above"),
|
|
33
36
|
React.createElement(ActionButton, { onClick: () => runCommand(addRows('bottom')) },
|
|
34
37
|
React.createElement(PlusIcon, null),
|
|
35
|
-
" Insert
|
|
36
|
-
rows
|
|
38
|
+
" Insert ",
|
|
39
|
+
rows,
|
|
40
|
+
" below"),
|
|
37
41
|
React.createElement(ActionButton, { onClick: () => setColumnAction(() => addColumns('left')) },
|
|
38
42
|
React.createElement(PlusIcon, null),
|
|
39
43
|
" Insert ",
|
|
@@ -53,6 +57,9 @@ export const ContextMenu = ({ view, close, }) => {
|
|
|
53
57
|
React.createElement(GrayDeleteIcon, null),
|
|
54
58
|
" Delete ",
|
|
55
59
|
columns),
|
|
60
|
+
(isCellSelectionMerged || isCellSelectionSplittable) && React.createElement(Separator, null),
|
|
61
|
+
isCellSelectionMerged && (React.createElement(ActionButton, { onClick: () => runCommand(mergeCellsWithSpace, true) }, "Merge cells")),
|
|
62
|
+
isCellSelectionSplittable && (React.createElement(ActionButton, { onClick: () => runCommand(splitCell, true) }, "Split cells")),
|
|
56
63
|
React.createElement(ColumnChangeWarningDialog, { isOpen: !!columnAction, primaryAction: () => {
|
|
57
64
|
if (columnAction) {
|
|
58
65
|
runCommand(columnAction, true);
|
package/dist/es/versions.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const VERSION = '2.0.
|
|
1
|
+
export const VERSION = '2.0.7-LEAN-3724.0';
|
|
2
2
|
export const MATHJAX_VERSION = '3.2.2';
|
package/dist/types/commands.d.ts
CHANGED
|
@@ -68,4 +68,5 @@ interface NodeWithPosition {
|
|
|
68
68
|
export declare const insertTableFootnote: (node: ManuscriptNode, position: number, view: EditorView, inlineFootnote?: NodeWithPosition) => void;
|
|
69
69
|
export declare const addRows: (direction: 'top' | 'bottom') => (state: EditorState, dispatch?: ((tr: Transaction) => void) | undefined) => boolean;
|
|
70
70
|
export declare const addColumns: (direction: 'right' | 'left') => (state: EditorState, dispatch?: ((tr: Transaction) => void) | undefined) => boolean;
|
|
71
|
+
export declare function mergeCellsWithSpace(state: EditorState, dispatch?: (tr: Transaction) => void): boolean;
|
|
71
72
|
export {};
|
package/dist/types/versions.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const VERSION = "2.0.
|
|
1
|
+
export declare const VERSION = "2.0.7-LEAN-3724.0";
|
|
2
2
|
export declare const MATHJAX_VERSION = "3.2.2";
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@manuscripts/body-editor",
|
|
3
3
|
"description": "Prosemirror components for editing and viewing manuscripts",
|
|
4
|
-
"version": "2.0.
|
|
4
|
+
"version": "2.0.7-LEAN-3724.0",
|
|
5
5
|
"repository": "github:Atypon-OpenSource/manuscripts-body-editor",
|
|
6
6
|
"license": "Apache-2.0",
|
|
7
7
|
"main": "dist/cjs",
|