@pie-lib/editable-html 9.5.13 → 10.0.0-beta.1
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/CHANGELOG.md +0 -302
- package/lib/components.js +116 -0
- package/lib/components.js.map +1 -0
- package/lib/editor.js +418 -103
- package/lib/editor.js.map +1 -1
- package/lib/index.js +101 -155
- package/lib/index.js.map +1 -1
- package/lib/new-serialization.js +320 -0
- package/lib/new-serialization.js.map +1 -0
- package/lib/old-serialization.js +330 -0
- package/lib/parse-html.js +1 -1
- package/lib/parse-html.js.map +1 -1
- package/lib/plugins/characters/custom-popper.js +1 -1
- package/lib/plugins/characters/custom-popper.js.map +1 -1
- package/lib/plugins/characters/index.js +21 -19
- package/lib/plugins/characters/index.js.map +1 -1
- package/lib/plugins/characters/utils.js +1 -1
- package/lib/plugins/characters/utils.js.map +1 -1
- package/lib/plugins/hotKeys/index.js +67 -0
- package/lib/plugins/hotKeys/index.js.map +1 -0
- package/lib/plugins/image/alt-dialog.js +1 -6
- package/lib/plugins/image/alt-dialog.js.map +1 -1
- package/lib/plugins/image/component.js +70 -53
- package/lib/plugins/image/component.js.map +1 -1
- package/lib/plugins/image/image-toolbar.js +7 -9
- package/lib/plugins/image/image-toolbar.js.map +1 -1
- package/lib/plugins/image/index.js +83 -27
- package/lib/plugins/image/index.js.map +1 -1
- package/lib/plugins/image/insert-image-handler.js +72 -33
- package/lib/plugins/image/insert-image-handler.js.map +1 -1
- package/lib/plugins/index.js +23 -41
- package/lib/plugins/index.js.map +1 -1
- package/lib/plugins/list/index.js +64 -100
- package/lib/plugins/list/index.js.map +1 -1
- package/lib/plugins/math/index.js +86 -60
- package/lib/plugins/math/index.js.map +1 -1
- package/lib/plugins/media/index.js +202 -132
- package/lib/plugins/media/index.js.map +1 -1
- package/lib/plugins/media/media-dialog.js +17 -16
- package/lib/plugins/media/media-dialog.js.map +1 -1
- package/lib/plugins/media/media-toolbar.js +3 -3
- package/lib/plugins/media/media-toolbar.js.map +1 -1
- package/lib/plugins/media/media-wrapper.js +21 -58
- package/lib/plugins/media/media-wrapper.js.map +1 -1
- package/lib/plugins/respArea/drag-in-the-blank/choice.js +3 -3
- package/lib/plugins/respArea/drag-in-the-blank/choice.js.map +1 -1
- package/lib/plugins/respArea/drag-in-the-blank/index.js +3 -2
- package/lib/plugins/respArea/drag-in-the-blank/index.js.map +1 -1
- package/lib/plugins/respArea/explicit-constructed-response/index.js +3 -2
- package/lib/plugins/respArea/explicit-constructed-response/index.js.map +1 -1
- package/lib/plugins/respArea/icons/index.js +13 -15
- package/lib/plugins/respArea/icons/index.js.map +1 -1
- package/lib/plugins/respArea/index.js +87 -53
- package/lib/plugins/respArea/index.js.map +1 -1
- package/lib/plugins/respArea/inline-dropdown/index.js +4 -3
- package/lib/plugins/respArea/inline-dropdown/index.js.map +1 -1
- package/lib/plugins/respArea/utils.js +17 -20
- package/lib/plugins/respArea/utils.js.map +1 -1
- package/lib/plugins/table/icons/index.js +1 -1
- package/lib/plugins/table/icons/index.js.map +1 -1
- package/lib/plugins/table/index.js +381 -212
- package/lib/plugins/table/index.js.map +1 -1
- package/lib/plugins/table/table-toolbar.js +5 -6
- package/lib/plugins/table/table-toolbar.js.map +1 -1
- package/lib/plugins/toolbar/default-toolbar.js +55 -11
- package/lib/plugins/toolbar/default-toolbar.js.map +1 -1
- package/lib/plugins/toolbar/done-button.js +1 -1
- package/lib/plugins/toolbar/done-button.js.map +1 -1
- package/lib/plugins/toolbar/editor-and-toolbar.js +186 -232
- package/lib/plugins/toolbar/editor-and-toolbar.js.map +1 -1
- package/lib/plugins/toolbar/index.js +1 -2
- package/lib/plugins/toolbar/index.js.map +1 -1
- package/lib/plugins/toolbar/toolbar-buttons.js +1 -1
- package/lib/plugins/toolbar/toolbar-buttons.js.map +1 -1
- package/lib/plugins/toolbar/toolbar.js +253 -239
- package/lib/plugins/toolbar/toolbar.js.map +1 -1
- package/lib/plugins/utils.js +27 -2
- package/lib/plugins/utils.js.map +1 -1
- package/lib/serialization.js +1 -1
- package/lib/serialization.js.map +1 -1
- package/lib/slate-editor.js +302 -0
- package/lib/test-serializer.js +189 -0
- package/lib/test-serializer.js.map +1 -0
- package/lib/theme.js +1 -1
- package/lib/theme.js.map +1 -1
- package/package.json +18 -14
- package/playground/image/data.js +20 -20
- package/playground/image/index.html +22 -20
- package/playground/image/index.jsx +12 -10
- package/playground/index.html +25 -23
- package/playground/mathquill/index.html +23 -20
- package/playground/mathquill/index.jsx +18 -22
- package/playground/prod-test/index.html +24 -20
- package/playground/prod-test/index.jsx +5 -3
- package/playground/schema-override/data.js +10 -10
- package/playground/schema-override/image-plugin.jsx +3 -4
- package/playground/schema-override/index.html +21 -19
- package/playground/schema-override/index.jsx +13 -14
- package/playground/serialization/data.js +10 -10
- package/playground/serialization/image-plugin.jsx +3 -4
- package/playground/serialization/index.html +22 -20
- package/playground/table-examples.html +5 -8
- package/playground/webpack.config.js +10 -10
- package/src/components.js +135 -0
- package/src/editor.jsx +478 -141
- package/src/index.jsx +71 -95
- package/src/new-serialization.jsx +291 -0
- package/src/parse-html.js +1 -1
- package/src/plugins/characters/custom-popper.js +7 -7
- package/src/plugins/characters/index.jsx +33 -34
- package/src/plugins/characters/utils.js +81 -81
- package/src/plugins/hotKeys/index.js +54 -0
- package/src/plugins/image/alt-dialog.jsx +4 -5
- package/src/plugins/image/component.jsx +106 -89
- package/src/plugins/image/image-toolbar.jsx +27 -19
- package/src/plugins/image/index.jsx +75 -43
- package/src/plugins/image/insert-image-handler.js +62 -27
- package/src/plugins/index.jsx +23 -41
- package/src/plugins/list/index.jsx +70 -95
- package/src/plugins/math/index.jsx +102 -82
- package/src/plugins/media/index.jsx +159 -124
- package/src/plugins/media/media-dialog.js +98 -71
- package/src/plugins/media/media-toolbar.jsx +8 -8
- package/src/plugins/media/media-wrapper.jsx +29 -30
- package/src/plugins/respArea/drag-in-the-blank/choice.jsx +21 -19
- package/src/plugins/respArea/drag-in-the-blank/index.jsx +14 -11
- package/src/plugins/respArea/explicit-constructed-response/index.jsx +7 -6
- package/src/plugins/respArea/icons/index.jsx +11 -14
- package/src/plugins/respArea/index.jsx +92 -52
- package/src/plugins/respArea/inline-dropdown/index.jsx +9 -8
- package/src/plugins/respArea/utils.jsx +26 -35
- package/src/plugins/table/icons/index.jsx +17 -11
- package/src/plugins/table/index.jsx +288 -231
- package/src/plugins/table/table-toolbar.jsx +15 -11
- package/src/plugins/toolbar/default-toolbar.jsx +65 -19
- package/src/plugins/toolbar/done-button.jsx +4 -4
- package/src/plugins/toolbar/editor-and-toolbar.jsx +150 -145
- package/src/plugins/toolbar/index.jsx +2 -3
- package/src/plugins/toolbar/toolbar-buttons.jsx +11 -11
- package/src/plugins/toolbar/toolbar.jsx +244 -221
- package/src/plugins/utils.js +21 -4
- package/src/serialization.jsx +32 -32
- package/src/test-serializer.js +139 -0
- package/src/test-serializer.js.rej +20 -0
|
@@ -1,68 +1,81 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import
|
|
3
|
-
import { Block } from 'slate';
|
|
2
|
+
import { Node as SlateNode, Editor, Transforms } from 'slate';
|
|
4
3
|
import debug from 'debug';
|
|
5
4
|
import GridOn from '@material-ui/icons/GridOn';
|
|
6
5
|
import TableToolbar from './table-toolbar';
|
|
7
6
|
import PropTypes from 'prop-types';
|
|
8
|
-
import
|
|
9
|
-
import {
|
|
7
|
+
import { jsx } from 'slate-hyperscript';
|
|
8
|
+
import { makeStyles } from '@material-ui/styles';
|
|
10
9
|
import convert from 'react-attr-converter';
|
|
11
10
|
import { object as toStyleObject } from 'to-style';
|
|
11
|
+
import get from 'lodash/get';
|
|
12
|
+
import omit from 'lodash/omit';
|
|
13
|
+
import reduce from 'lodash/reduce';
|
|
12
14
|
|
|
13
15
|
const log = debug('@pie-lib:editable-html:plugins:table');
|
|
14
16
|
|
|
15
|
-
const Table =
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
const nodeAttributes = dataToAttributes(props.node.data);
|
|
17
|
+
const Table = React.forwardRef(props => {
|
|
18
|
+
const nodeAttributes = omit(dataToAttributes(props.element.data), 'newTable');
|
|
19
|
+
const attrs = omit(props.attributes, 'newTable');
|
|
19
20
|
|
|
20
21
|
return (
|
|
21
|
-
<table
|
|
22
|
-
|
|
23
|
-
{...props.attributes}
|
|
24
|
-
{...nodeAttributes}
|
|
25
|
-
onFocus={props.onFocus}
|
|
26
|
-
onBlur={props.onBlur}
|
|
27
|
-
>
|
|
28
|
-
<tbody>{props.children}</tbody>
|
|
22
|
+
<table {...attrs} {...nodeAttributes} onFocus={props.onFocus} onBlur={props.onBlur}>
|
|
23
|
+
{props.children}
|
|
29
24
|
</table>
|
|
30
25
|
);
|
|
31
26
|
});
|
|
32
27
|
|
|
33
28
|
Table.propTypes = {
|
|
34
29
|
attributes: PropTypes.object,
|
|
30
|
+
element: PropTypes.object,
|
|
35
31
|
onFocus: PropTypes.func,
|
|
36
32
|
onBlur: PropTypes.func,
|
|
37
|
-
node:
|
|
38
|
-
|
|
33
|
+
node: PropTypes.shape({
|
|
34
|
+
type: PropTypes.string,
|
|
35
|
+
children: PropTypes.array,
|
|
36
|
+
data: PropTypes.object
|
|
37
|
+
}),
|
|
38
|
+
children: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node]).isRequired
|
|
39
39
|
};
|
|
40
40
|
|
|
41
|
-
const TableRow = (props
|
|
41
|
+
const TableRow = React.forwardRef(props => <tr {...props.attributes}>{props.children}</tr>);
|
|
42
42
|
|
|
43
43
|
TableRow.propTypes = {
|
|
44
44
|
attributes: PropTypes.object,
|
|
45
45
|
onFocus: PropTypes.func,
|
|
46
46
|
onBlur: PropTypes.func,
|
|
47
|
-
children: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node]).isRequired
|
|
47
|
+
children: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node]).isRequired
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const TableBody = React.forwardRef(props => <tbody {...props.attributes}>{props.children}</tbody>);
|
|
51
|
+
|
|
52
|
+
TableBody.propTypes = {
|
|
53
|
+
attributes: PropTypes.object,
|
|
54
|
+
onFocus: PropTypes.func,
|
|
55
|
+
onBlur: PropTypes.func,
|
|
56
|
+
children: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node]).isRequired
|
|
48
57
|
};
|
|
49
58
|
|
|
50
|
-
const
|
|
59
|
+
const useCellStyles = makeStyles({
|
|
51
60
|
td: {
|
|
52
|
-
minWidth: '25px'
|
|
53
|
-
}
|
|
54
|
-
})
|
|
55
|
-
|
|
61
|
+
minWidth: '25px'
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
const TableCell = React.forwardRef(props => {
|
|
66
|
+
const classes = useCellStyles();
|
|
67
|
+
const { node } = props;
|
|
68
|
+
const Tag = get(node, 'data.header') ? 'th' : 'td';
|
|
56
69
|
|
|
57
|
-
const nodeAttributes = dataToAttributes(props.
|
|
70
|
+
const nodeAttributes = dataToAttributes(props.element.data);
|
|
58
71
|
delete nodeAttributes.header;
|
|
59
72
|
|
|
60
73
|
return (
|
|
61
74
|
<Tag
|
|
62
75
|
{...props.attributes}
|
|
63
76
|
{...nodeAttributes}
|
|
64
|
-
colSpan={
|
|
65
|
-
className={
|
|
77
|
+
colSpan={get(node, 'data.colspan')}
|
|
78
|
+
className={classes[Tag]}
|
|
66
79
|
onFocus={props.onFocus}
|
|
67
80
|
onBlur={props.onBlur}
|
|
68
81
|
>
|
|
@@ -72,134 +85,234 @@ const TableCell = withStyles(() => ({
|
|
|
72
85
|
});
|
|
73
86
|
|
|
74
87
|
TableCell.propTypes = {
|
|
88
|
+
node: PropTypes.object,
|
|
89
|
+
element: PropTypes.object,
|
|
75
90
|
attributes: PropTypes.object,
|
|
76
91
|
onFocus: PropTypes.func,
|
|
77
92
|
onBlur: PropTypes.func,
|
|
78
|
-
children: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node]).isRequired
|
|
93
|
+
children: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node]).isRequired
|
|
79
94
|
};
|
|
80
95
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
if (!addedTable) {
|
|
85
|
-
return;
|
|
96
|
+
const getAncestorByType = (editor, type) => {
|
|
97
|
+
if (!editor || !type) {
|
|
98
|
+
return null;
|
|
86
99
|
}
|
|
87
100
|
|
|
88
|
-
|
|
101
|
+
const ancestors = SlateNode.ancestors(editor, Editor.path(editor, editor.selection), {
|
|
102
|
+
reverse: true
|
|
103
|
+
});
|
|
89
104
|
|
|
90
|
-
const
|
|
105
|
+
for (const [ancestor, ancestorPath] of ancestors) {
|
|
106
|
+
if (ancestor.type === type) {
|
|
107
|
+
return [ancestor, ancestorPath];
|
|
108
|
+
}
|
|
109
|
+
}
|
|
91
110
|
|
|
92
|
-
|
|
111
|
+
return null;
|
|
93
112
|
};
|
|
94
113
|
|
|
95
|
-
|
|
96
|
-
const
|
|
97
|
-
|
|
98
|
-
});
|
|
114
|
+
const moveToBeginningOfTable = editor => {
|
|
115
|
+
const [tableBlock, tablePath] = getAncestorByType(editor, 'table');
|
|
116
|
+
let firstTdPath;
|
|
99
117
|
|
|
100
|
-
|
|
118
|
+
for (const [descendant, descendantPath] of SlateNode.descendants(tableBlock, { reverse: true })) {
|
|
119
|
+
if (descendant.type === 'td') {
|
|
120
|
+
firstTdPath = descendantPath;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
101
123
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
const block = core.schema.blocks[key];
|
|
124
|
+
Transforms.select(editor, [...tablePath, ...firstTdPath]);
|
|
125
|
+
};
|
|
105
126
|
|
|
106
|
-
|
|
107
|
-
if (block.nodes[0].types) {
|
|
108
|
-
block.nodes[0] = {
|
|
109
|
-
type: block.nodes[0].types[0],
|
|
110
|
-
};
|
|
111
|
-
}
|
|
127
|
+
const TABLE_TYPES = ['tbody', 'tr', 'td', 'table'];
|
|
112
128
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
}
|
|
129
|
+
export default (opts, toolbarPlugins /* : {toolbar: {}}[] */) => {
|
|
130
|
+
const core = {
|
|
131
|
+
utils: {}
|
|
132
|
+
};
|
|
118
133
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
134
|
+
core.utils.createTable = (row = 2, columns = 2) => {
|
|
135
|
+
const tableRows = [];
|
|
136
|
+
const rowLength = new Array(row).fill(0).length;
|
|
137
|
+
const columnsLength = new Array(columns).fill(0).length;
|
|
138
|
+
|
|
139
|
+
for (let i = 0; i < rowLength; i++) {
|
|
140
|
+
const tableRow = { type: 'tr', children: [] };
|
|
141
|
+
|
|
142
|
+
for (let j = 0; j < columnsLength; j++) {
|
|
143
|
+
tableRow.children.push({
|
|
144
|
+
type: 'td',
|
|
145
|
+
children: [
|
|
146
|
+
{
|
|
147
|
+
text: ''
|
|
148
|
+
}
|
|
149
|
+
]
|
|
150
|
+
});
|
|
124
151
|
}
|
|
125
|
-
});
|
|
126
|
-
}
|
|
127
152
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
return
|
|
153
|
+
tableRows.push(tableRow);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
return {
|
|
157
|
+
type: 'table',
|
|
158
|
+
children: [
|
|
159
|
+
{
|
|
160
|
+
type: 'tbody',
|
|
161
|
+
children: tableRows
|
|
162
|
+
}
|
|
163
|
+
]
|
|
164
|
+
};
|
|
132
165
|
};
|
|
133
166
|
|
|
167
|
+
core.utils.getTableBlock = editor => getAncestorByType(editor, 'table');
|
|
168
|
+
|
|
169
|
+
core.utils.isSelectionInTable = editor => !!core.utils.getTableBlock(editor);
|
|
170
|
+
|
|
134
171
|
core.utils.createTableWithOptions = (row, columns, extra) => {
|
|
135
172
|
const createdTable = core.utils.createTable(row, columns);
|
|
136
|
-
const newTable =
|
|
137
|
-
...createdTable.toJSON(),
|
|
138
|
-
...extra,
|
|
139
|
-
});
|
|
173
|
+
const newTable = { ...createdTable, ...extra };
|
|
140
174
|
|
|
141
175
|
return newTable;
|
|
142
176
|
};
|
|
143
177
|
|
|
144
178
|
core.toolbar = {
|
|
145
179
|
icon: <GridOn />,
|
|
146
|
-
onClick:
|
|
180
|
+
onClick: editor => {
|
|
147
181
|
log('insert table');
|
|
148
|
-
const change = value.change();
|
|
149
182
|
const newTable = core.utils.createTableWithOptions(2, 2, {
|
|
150
183
|
data: {
|
|
151
184
|
border: '1',
|
|
152
|
-
newTable: true
|
|
153
|
-
}
|
|
185
|
+
newTable: true
|
|
186
|
+
}
|
|
154
187
|
});
|
|
155
188
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
moveFocusToBeginningOfTable(change);
|
|
159
|
-
onChange(change);
|
|
189
|
+
editor.insertNode(newTable);
|
|
190
|
+
moveToBeginningOfTable(editor, newTable);
|
|
160
191
|
},
|
|
161
|
-
supports: (node, value) => node && node.object === 'block' && core.utils.isSelectionInTable(value),
|
|
162
192
|
/**
|
|
163
193
|
* Note - the node may not be a table node - it may be a node inside a table.
|
|
164
194
|
*/
|
|
165
|
-
customToolbar: (node, value, onToolbarDone) => {
|
|
195
|
+
customToolbar: (node, value, editor, onToolbarDone) => {
|
|
166
196
|
log('[customToolbar] node.data: ', node.data);
|
|
167
197
|
|
|
168
|
-
const tableBlock = core.utils.getTableBlock(
|
|
198
|
+
const [tableBlock] = core.utils.getTableBlock(editor);
|
|
169
199
|
log('[customToolbar] tableBlock: ', tableBlock);
|
|
170
200
|
|
|
171
|
-
const hasBorder = () =>
|
|
201
|
+
const hasBorder = () => get(tableBlock, 'data.border') !== '0';
|
|
172
202
|
const addRow = () => {
|
|
173
|
-
const
|
|
174
|
-
|
|
175
|
-
|
|
203
|
+
const [trNode, trPath] = getAncestorByType(editor, 'tr');
|
|
204
|
+
|
|
205
|
+
log('[addRow]');
|
|
206
|
+
|
|
207
|
+
if (trNode) {
|
|
208
|
+
const newTr = { type: 'tr', children: [] };
|
|
209
|
+
const columnsLength = trNode.children.length;
|
|
210
|
+
|
|
211
|
+
for (let i = 0; i < columnsLength; i++) {
|
|
212
|
+
newTr.children.push({
|
|
213
|
+
type: 'td',
|
|
214
|
+
children: [
|
|
215
|
+
{
|
|
216
|
+
text: ''
|
|
217
|
+
}
|
|
218
|
+
]
|
|
219
|
+
});
|
|
220
|
+
}
|
|
176
221
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
onToolbarDone(change, false);
|
|
222
|
+
Transforms.insertNodes(editor, [newTr], { at: trPath });
|
|
223
|
+
}
|
|
180
224
|
};
|
|
181
225
|
|
|
182
226
|
const removeRow = () => {
|
|
183
|
-
const
|
|
184
|
-
|
|
227
|
+
const [tBodyNode, tBodyPath] = getAncestorByType(editor, 'tbody');
|
|
228
|
+
|
|
229
|
+
log('[removeRow]');
|
|
230
|
+
|
|
231
|
+
if (tBodyPath) {
|
|
232
|
+
if (tBodyNode.children.length > 1) {
|
|
233
|
+
const [, trPath] = getAncestorByType(editor, 'tr');
|
|
234
|
+
|
|
235
|
+
log('[removeRow]');
|
|
236
|
+
|
|
237
|
+
if (trPath) {
|
|
238
|
+
Transforms.removeNodes(editor, { at: trPath });
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
};
|
|
243
|
+
|
|
244
|
+
const addColumn = () => {
|
|
245
|
+
const [tBodyNode, tBodyPath] = getAncestorByType(editor, 'tbody');
|
|
246
|
+
|
|
247
|
+
log('[addColumn]');
|
|
248
|
+
|
|
249
|
+
if (tBodyNode) {
|
|
250
|
+
const emptyTd = {
|
|
251
|
+
type: 'td',
|
|
252
|
+
children: [{ text: '' }]
|
|
253
|
+
};
|
|
254
|
+
const trElements = Editor.nodes(editor, {
|
|
255
|
+
at: tBodyPath, // Path of Editor
|
|
256
|
+
match: node => 'tr' === node.type
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
for (const [trNode, nodePath] of trElements) {
|
|
260
|
+
Transforms.insertNodes(editor, [emptyTd], {
|
|
261
|
+
at: [...nodePath, trNode.children.length]
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
}
|
|
185
265
|
};
|
|
186
266
|
|
|
187
267
|
const removeColumn = () => {
|
|
188
|
-
const
|
|
189
|
-
|
|
268
|
+
const [tBodyNode, tBodyPath] = getAncestorByType(editor, 'tbody');
|
|
269
|
+
|
|
270
|
+
log('[addColumn]');
|
|
271
|
+
|
|
272
|
+
if (tBodyNode) {
|
|
273
|
+
const currentPath = Editor.path(editor, editor.selection);
|
|
274
|
+
const columnIndex = currentPath[currentPath.length - 2];
|
|
275
|
+
const trElements = Editor.nodes(editor, {
|
|
276
|
+
at: tBodyPath, // Path of Editor
|
|
277
|
+
match: node => 'tr' === node.type
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
for (const [trNode, nodePath] of trElements) {
|
|
281
|
+
if (trNode.children.length > 1) {
|
|
282
|
+
Transforms.removeNodes(editor, { at: [...nodePath, columnIndex] });
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
190
286
|
};
|
|
191
287
|
|
|
192
288
|
const removeTable = () => {
|
|
193
|
-
const
|
|
194
|
-
|
|
289
|
+
const [tableNode, tablePath] = getAncestorByType(editor, 'table');
|
|
290
|
+
|
|
291
|
+
editor.apply({
|
|
292
|
+
type: 'remove_node',
|
|
293
|
+
path: tablePath,
|
|
294
|
+
node: tableNode
|
|
295
|
+
});
|
|
195
296
|
};
|
|
196
297
|
|
|
197
298
|
const toggleBorder = () => {
|
|
198
299
|
const { data } = tableBlock;
|
|
199
|
-
const update =
|
|
300
|
+
const update = {
|
|
301
|
+
...data,
|
|
302
|
+
border: hasBorder() ? '0' : '1'
|
|
303
|
+
};
|
|
304
|
+
const [, tablePath] = getAncestorByType(editor, 'table');
|
|
305
|
+
|
|
200
306
|
log('[toggleBorder] update: ', update);
|
|
201
|
-
|
|
202
|
-
|
|
307
|
+
|
|
308
|
+
editor.apply({
|
|
309
|
+
type: 'set_node',
|
|
310
|
+
path: tablePath,
|
|
311
|
+
properties: {
|
|
312
|
+
data: node.data
|
|
313
|
+
},
|
|
314
|
+
newProperties: { data: update }
|
|
315
|
+
});
|
|
203
316
|
};
|
|
204
317
|
|
|
205
318
|
const onDone = () => {
|
|
@@ -209,9 +322,9 @@ export default (opts, toolbarPlugins /* : {toolbar: {}}[] */) => {
|
|
|
209
322
|
|
|
210
323
|
const Tb = () => (
|
|
211
324
|
<TableToolbar
|
|
325
|
+
editor={editor}
|
|
212
326
|
plugins={toolbarPlugins}
|
|
213
|
-
onChange={
|
|
214
|
-
value={value}
|
|
327
|
+
onChange={c => onToolbarDone(c, false)}
|
|
215
328
|
onAddRow={addRow}
|
|
216
329
|
onRemoveRow={removeRow}
|
|
217
330
|
onAddColumn={addColumn}
|
|
@@ -223,91 +336,27 @@ export default (opts, toolbarPlugins /* : {toolbar: {}}[] */) => {
|
|
|
223
336
|
/>
|
|
224
337
|
);
|
|
225
338
|
return Tb;
|
|
226
|
-
}
|
|
339
|
+
}
|
|
227
340
|
};
|
|
228
341
|
|
|
229
|
-
|
|
342
|
+
core.supports = (node, editor) => TABLE_TYPES.includes(node.type);
|
|
343
|
+
|
|
344
|
+
const Node = props => {
|
|
230
345
|
switch (props.node.type) {
|
|
231
346
|
case 'table':
|
|
232
347
|
return <Table {...props} onFocus={opts.onFocus} onBlur={opts.onBlur} />;
|
|
233
|
-
case '
|
|
348
|
+
case 'tbody':
|
|
349
|
+
return <TableBody {...props} onFocus={opts.onFocus} onBlur={opts.onBlur} />;
|
|
350
|
+
case 'tr':
|
|
234
351
|
return <TableRow {...props} />;
|
|
235
|
-
case '
|
|
352
|
+
case 'td':
|
|
236
353
|
return <TableCell {...props} onFocus={opts.onFocus} onBlur={opts.onBlur} />;
|
|
237
354
|
default:
|
|
238
355
|
return null;
|
|
239
356
|
}
|
|
240
357
|
};
|
|
241
358
|
Node.propTypes = {
|
|
242
|
-
node: PropTypes.object
|
|
243
|
-
};
|
|
244
|
-
|
|
245
|
-
core.normalizeNode = (node) => {
|
|
246
|
-
if (node.object !== 'document') {
|
|
247
|
-
return;
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
const tableAdded = node.findDescendant((d) => d.data && d.data.get('newTable'));
|
|
251
|
-
|
|
252
|
-
if (!tableAdded) {
|
|
253
|
-
return;
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
const nodeToSearch = node.getParent(tableAdded.key) || node;
|
|
257
|
-
let shouldAddTextAfterNode = false;
|
|
258
|
-
const indexToNotHaveTableOn = nodeToSearch.nodes.size - 1;
|
|
259
|
-
const indexOfLastTable = nodeToSearch.nodes.findLastIndex((d) => d.type === 'table');
|
|
260
|
-
|
|
261
|
-
// if the last table in the document is of type table, we need to do the change
|
|
262
|
-
if (indexOfLastTable === indexToNotHaveTableOn) {
|
|
263
|
-
shouldAddTextAfterNode = true;
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
if (!shouldAddTextAfterNode) {
|
|
267
|
-
return;
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
return (change) => {
|
|
271
|
-
if (shouldAddTextAfterNode) {
|
|
272
|
-
const tableJSON = tableAdded.toJSON();
|
|
273
|
-
|
|
274
|
-
// we remove the table node because otherwise we can't add the empty block after it
|
|
275
|
-
// we need a block that contains text in order to do it
|
|
276
|
-
change.removeNodeByKey(tableAdded.key);
|
|
277
|
-
|
|
278
|
-
const newBlock = Block.create({
|
|
279
|
-
object: 'block',
|
|
280
|
-
type: 'div',
|
|
281
|
-
});
|
|
282
|
-
|
|
283
|
-
// we add an empty block but that it's going to be normalized
|
|
284
|
-
// because it will add the empty text to it like it should
|
|
285
|
-
change.insertBlock(newBlock);
|
|
286
|
-
|
|
287
|
-
change.withoutNormalization(() => {
|
|
288
|
-
// we do these changes without normalization
|
|
289
|
-
|
|
290
|
-
// we get the text previous to the new block added
|
|
291
|
-
const prevText = change.value.document.getPreviousText(newBlock.key);
|
|
292
|
-
|
|
293
|
-
if (prevText) {
|
|
294
|
-
// we move focus to the previous text
|
|
295
|
-
change.moveFocusTo(prevText.key, prevText.text?.length).moveAnchorTo(prevText.key, prevText.text?.length);
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
// we insert the table block between the first block with text and the last block with text
|
|
299
|
-
change.insertBlock({
|
|
300
|
-
...tableJSON,
|
|
301
|
-
data: {
|
|
302
|
-
...tableJSON.data,
|
|
303
|
-
newTable: true,
|
|
304
|
-
},
|
|
305
|
-
});
|
|
306
|
-
|
|
307
|
-
moveFocusToBeginningOfTable(change);
|
|
308
|
-
});
|
|
309
|
-
}
|
|
310
|
-
};
|
|
359
|
+
node: PropTypes.object
|
|
311
360
|
};
|
|
312
361
|
|
|
313
362
|
core.renderNode = Node;
|
|
@@ -315,7 +364,7 @@ export default (opts, toolbarPlugins /* : {toolbar: {}}[] */) => {
|
|
|
315
364
|
return core;
|
|
316
365
|
};
|
|
317
366
|
|
|
318
|
-
export const parseStyleString =
|
|
367
|
+
export const parseStyleString = s => {
|
|
319
368
|
const regex = /([\w-]*)\s*:\s*([^;]*)/g;
|
|
320
369
|
let match;
|
|
321
370
|
const result = {};
|
|
@@ -325,9 +374,9 @@ export const parseStyleString = (s) => {
|
|
|
325
374
|
return result;
|
|
326
375
|
};
|
|
327
376
|
|
|
328
|
-
export const reactAttributes =
|
|
377
|
+
export const reactAttributes = o => toStyleObject(o, { camelize: true, addUnits: false });
|
|
329
378
|
|
|
330
|
-
const attributesToMap =
|
|
379
|
+
const attributesToMap = el => (acc, attribute) => {
|
|
331
380
|
const value = el.getAttribute(attribute);
|
|
332
381
|
if (value) {
|
|
333
382
|
if (attribute === 'style') {
|
|
@@ -341,17 +390,17 @@ const attributesToMap = (el) => (acc, attribute) => {
|
|
|
341
390
|
return acc;
|
|
342
391
|
};
|
|
343
392
|
|
|
344
|
-
const dataToAttributes =
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
acc
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
|
|
393
|
+
const dataToAttributes = data => {
|
|
394
|
+
return reduce(
|
|
395
|
+
data,
|
|
396
|
+
(acc, v, name) => {
|
|
397
|
+
if (v) {
|
|
398
|
+
acc[convert(name)] = v;
|
|
399
|
+
}
|
|
400
|
+
return acc;
|
|
401
|
+
},
|
|
402
|
+
{}
|
|
403
|
+
);
|
|
355
404
|
};
|
|
356
405
|
|
|
357
406
|
const attributes = ['border', 'cellpadding', 'cellspacing', 'class', 'style'];
|
|
@@ -370,71 +419,79 @@ export const serialization = {
|
|
|
370
419
|
: el.children;
|
|
371
420
|
const c = Array.from(children);
|
|
372
421
|
|
|
373
|
-
return
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
422
|
+
return jsx(
|
|
423
|
+
'element',
|
|
424
|
+
{
|
|
425
|
+
type: 'table',
|
|
426
|
+
data: attributes.reduce(attributesToMap(el), {})
|
|
427
|
+
},
|
|
428
|
+
next(c)
|
|
429
|
+
);
|
|
430
|
+
}
|
|
431
|
+
case 'tbody': {
|
|
432
|
+
return jsx(
|
|
433
|
+
'element',
|
|
434
|
+
{
|
|
435
|
+
type: 'tbody'
|
|
436
|
+
},
|
|
437
|
+
next(el.childNodes)
|
|
438
|
+
);
|
|
379
439
|
}
|
|
380
|
-
|
|
381
440
|
case 'th': {
|
|
382
|
-
return
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
441
|
+
return jsx(
|
|
442
|
+
'element',
|
|
443
|
+
{
|
|
444
|
+
type: 'th',
|
|
445
|
+
data: cellAttributes.reduce(attributesToMap(el), { header: true })
|
|
446
|
+
},
|
|
447
|
+
next(el.childNodes)
|
|
448
|
+
);
|
|
388
449
|
}
|
|
389
|
-
|
|
390
450
|
case 'tr': {
|
|
391
|
-
return
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
451
|
+
return jsx(
|
|
452
|
+
'element',
|
|
453
|
+
{
|
|
454
|
+
type: 'tr'
|
|
455
|
+
},
|
|
456
|
+
next(Array.from(el.children))
|
|
457
|
+
);
|
|
396
458
|
}
|
|
397
|
-
|
|
398
459
|
case 'td': {
|
|
399
|
-
return
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
460
|
+
return jsx(
|
|
461
|
+
'element',
|
|
462
|
+
{
|
|
463
|
+
type: 'td',
|
|
464
|
+
data: cellAttributes.reduce(attributesToMap(el), { header: true })
|
|
465
|
+
},
|
|
466
|
+
next(el.childNodes)
|
|
467
|
+
);
|
|
405
468
|
}
|
|
406
469
|
}
|
|
407
470
|
},
|
|
408
471
|
serialize(object, children) {
|
|
409
|
-
if (object.object !== 'block') {
|
|
410
|
-
return;
|
|
411
|
-
}
|
|
412
|
-
|
|
413
472
|
switch (object.type) {
|
|
414
473
|
case 'table': {
|
|
415
474
|
const attributes = dataToAttributes(object.data);
|
|
416
|
-
|
|
417
475
|
return (
|
|
418
476
|
<table {...attributes}>
|
|
419
|
-
|
|
477
|
+
{children}
|
|
420
478
|
</table>
|
|
421
479
|
);
|
|
422
480
|
}
|
|
423
|
-
|
|
424
|
-
|
|
481
|
+
case 'tbody': {
|
|
482
|
+
return <tbody>{children}</tbody>;
|
|
483
|
+
}
|
|
484
|
+
case 'tr': {
|
|
425
485
|
return <tr>{children}</tr>;
|
|
426
486
|
}
|
|
427
|
-
|
|
428
|
-
case 'table_cell': {
|
|
487
|
+
case 'td': {
|
|
429
488
|
const attributes = dataToAttributes(object.data);
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
return <td {...attributes}>{children}</td>;
|
|
436
|
-
}
|
|
489
|
+
return <td {...attributes}>{children}</td>;
|
|
490
|
+
}
|
|
491
|
+
case 'th': {
|
|
492
|
+
const attributes = dataToAttributes(object.data);
|
|
493
|
+
return <th {...attributes}>{children}</th>;
|
|
437
494
|
}
|
|
438
495
|
}
|
|
439
|
-
}
|
|
496
|
+
}
|
|
440
497
|
};
|