@atlaskit/editor-plugin-table 9.3.4 → 9.3.5
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
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-table
|
|
2
2
|
|
|
3
|
+
## 9.3.5
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#108813](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/108813)
|
|
8
|
+
[`123953f8b2006`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/123953f8b2006) -
|
|
9
|
+
[ux] ED-26075 Unwrap content from nested table text block slices on paste
|
|
10
|
+
|
|
3
11
|
## 9.3.4
|
|
4
12
|
|
|
5
13
|
### Patch Changes
|
|
@@ -172,12 +172,58 @@ var transformSliceToFixHardBreakProblemOnCopyFromCell = exports.transformSliceTo
|
|
|
172
172
|
}
|
|
173
173
|
return slice;
|
|
174
174
|
};
|
|
175
|
+
var isNodeSingleCellTable = function isNodeSingleCellTable(node, schema) {
|
|
176
|
+
var _node$firstChild, _node$firstChild$firs, _node$firstChild$firs2;
|
|
177
|
+
return node.childCount === 1 && ((_node$firstChild = node.firstChild) === null || _node$firstChild === void 0 ? void 0 : _node$firstChild.type) === schema.nodes.tableRow && node.firstChild.childCount === 1 && (((_node$firstChild$firs = node.firstChild.firstChild) === null || _node$firstChild$firs === void 0 ? void 0 : _node$firstChild$firs.type) === schema.nodes.tableCell || ((_node$firstChild$firs2 = node.firstChild.firstChild) === null || _node$firstChild$firs2 === void 0 ? void 0 : _node$firstChild$firs2.type) === schema.nodes.tableHeader);
|
|
178
|
+
};
|
|
179
|
+
var isFragmentSingleCellTable = function isFragmentSingleCellTable(fragment, schema) {
|
|
180
|
+
return fragment.childCount === 1 && fragment.firstChild !== null && isNodeSingleCellTable(fragment.firstChild, schema);
|
|
181
|
+
};
|
|
182
|
+
var containsTextBlockChildren = function containsTextBlockChildren(fragment, schema) {
|
|
183
|
+
var containsTextBlock = false;
|
|
184
|
+
fragment.forEach(function (node) {
|
|
185
|
+
if (node.isTextblock) {
|
|
186
|
+
containsTextBlock = true;
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
return containsTextBlock;
|
|
190
|
+
};
|
|
175
191
|
var transformSliceToRemoveOpenTable = exports.transformSliceToRemoveOpenTable = function transformSliceToRemoveOpenTable(slice, schema) {
|
|
176
|
-
var _slice$content$
|
|
177
|
-
|
|
178
|
-
|
|
192
|
+
var _slice$content$firstC4;
|
|
193
|
+
if ((0, _platformFeatureFlags.fg)('platform_editor_nested_tables_paste_wrap_fix')) {
|
|
194
|
+
// Case 1: A slice of a textblock selection inside a nested table
|
|
195
|
+
// Prosemirror wraps nested textblock selections in their respective tables
|
|
196
|
+
// We are using `safeInsert` to paste nested tables, so we do not want to preserve this wrapping
|
|
197
|
+
|
|
198
|
+
// slice starts and ends inside a nested table at the same depth
|
|
199
|
+
if (slice.openStart >= 7 && slice.openEnd >= 7 && slice.openStart === slice.openEnd) {
|
|
200
|
+
var cleaned = slice;
|
|
201
|
+
var descendedDepth = 0;
|
|
202
|
+
var tableDepthDecrement = 2;
|
|
179
203
|
|
|
180
|
-
|
|
204
|
+
// if the slice is a single cell table and contains cells with single cell tables, descend into it until we find textblock children
|
|
205
|
+
if (isFragmentSingleCellTable(slice.content, schema)) {
|
|
206
|
+
var _slice$content$firstC2;
|
|
207
|
+
(_slice$content$firstC2 = slice.content.firstChild) === null || _slice$content$firstC2 === void 0 || _slice$content$firstC2.descendants(function (node, _pos, parent) {
|
|
208
|
+
if (isNodeSingleCellTable(node, schema)) {
|
|
209
|
+
descendedDepth += tableDepthDecrement;
|
|
210
|
+
} else if (node.type === schema.nodes.table) {
|
|
211
|
+
return false;
|
|
212
|
+
} else if (containsTextBlockChildren(node.content, schema)) {
|
|
213
|
+
descendedDepth += tableDepthDecrement;
|
|
214
|
+
// create a new slice with the content of the textblock children and the depth of the nested tables subtracted
|
|
215
|
+
cleaned = new _model.Slice(node.content, slice.openStart - descendedDepth - tableDepthDecrement, slice.openEnd - descendedDepth - tableDepthDecrement);
|
|
216
|
+
return false;
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
if (!cleaned.eq(slice)) {
|
|
221
|
+
return cleaned;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// Case 2: A slice entirely within a single CELL
|
|
181
227
|
if (
|
|
182
228
|
// starts and ends inside of a cell
|
|
183
229
|
slice.openStart >= 4 && slice.openEnd >= 4 &&
|
|
@@ -186,25 +232,28 @@ var transformSliceToRemoveOpenTable = exports.transformSliceToRemoveOpenTable =
|
|
|
186
232
|
// Ignored via go/ees005
|
|
187
233
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
188
234
|
slice.content.firstChild.type === schema.nodes.table) {
|
|
189
|
-
var _slice$content$
|
|
235
|
+
var _slice$content$firstC3;
|
|
236
|
+
// we're removing the table, tableRow and tableCell reducing the open depth by 3
|
|
237
|
+
var depthDecrement = 3;
|
|
238
|
+
|
|
190
239
|
// prosemirror-view has a bug that it duplicates table entry when selecting multiple paragraphs in a table cell.
|
|
191
240
|
// https://github.com/ProseMirror/prosemirror/issues/1270
|
|
192
241
|
// The structure becomes
|
|
193
242
|
// table(genuine) > tableRow(genuine) > table(duplicated) > tableRow(duplicated) > tableCell/tableHeader(genuine) > contents(genuine)
|
|
194
243
|
// As we are removing wrapping table anyway, we keep duplicated table and tableRow for simplicity
|
|
195
|
-
var
|
|
196
|
-
if (((_slice$content$
|
|
197
|
-
|
|
244
|
+
var _cleaned = slice;
|
|
245
|
+
if (((_slice$content$firstC3 = slice.content.firstChild) === null || _slice$content$firstC3 === void 0 || (_slice$content$firstC3 = _slice$content$firstC3.content) === null || _slice$content$firstC3 === void 0 || (_slice$content$firstC3 = _slice$content$firstC3.firstChild) === null || _slice$content$firstC3 === void 0 || (_slice$content$firstC3 = _slice$content$firstC3.content) === null || _slice$content$firstC3 === void 0 || (_slice$content$firstC3 = _slice$content$firstC3.firstChild) === null || _slice$content$firstC3 === void 0 ? void 0 : _slice$content$firstC3.type) === schema.nodes.table) {
|
|
246
|
+
_cleaned = new _model.Slice(slice.content.firstChild.content.firstChild.content, slice.openStart - 2, slice.openEnd - 2);
|
|
198
247
|
}
|
|
199
|
-
return new _model.Slice((0, _utils.flatmap)(
|
|
248
|
+
return new _model.Slice((0, _utils.flatmap)(_cleaned.content, unwrapContentFromTable), _cleaned.openStart - depthDecrement, _cleaned.openEnd - depthDecrement);
|
|
200
249
|
}
|
|
201
250
|
|
|
202
|
-
// Case
|
|
251
|
+
// Case 3: A slice starting within a CELL and ending outside the table
|
|
203
252
|
if (
|
|
204
253
|
// starts inside of a cell but ends outside of the starting table
|
|
205
254
|
slice.openStart >= 4 &&
|
|
206
255
|
// slice starts from a table node (and spans across more than one node)
|
|
207
|
-
slice.content.childCount > 1 && ((_slice$content$
|
|
256
|
+
slice.content.childCount > 1 && ((_slice$content$firstC4 = slice.content.firstChild) === null || _slice$content$firstC4 === void 0 ? void 0 : _slice$content$firstC4.type) === schema.nodes.table) {
|
|
208
257
|
// repoint the slice's cutting depth so that cell content where the slice starts
|
|
209
258
|
// does not get lifted out of the cell on paste
|
|
210
259
|
return new _model.Slice(slice.content, 1, slice.openEnd);
|
|
@@ -163,12 +163,58 @@ export const transformSliceToFixHardBreakProblemOnCopyFromCell = (slice, schema)
|
|
|
163
163
|
}
|
|
164
164
|
return slice;
|
|
165
165
|
};
|
|
166
|
+
const isNodeSingleCellTable = (node, schema) => {
|
|
167
|
+
var _node$firstChild, _node$firstChild$firs, _node$firstChild$firs2;
|
|
168
|
+
return node.childCount === 1 && ((_node$firstChild = node.firstChild) === null || _node$firstChild === void 0 ? void 0 : _node$firstChild.type) === schema.nodes.tableRow && node.firstChild.childCount === 1 && (((_node$firstChild$firs = node.firstChild.firstChild) === null || _node$firstChild$firs === void 0 ? void 0 : _node$firstChild$firs.type) === schema.nodes.tableCell || ((_node$firstChild$firs2 = node.firstChild.firstChild) === null || _node$firstChild$firs2 === void 0 ? void 0 : _node$firstChild$firs2.type) === schema.nodes.tableHeader);
|
|
169
|
+
};
|
|
170
|
+
const isFragmentSingleCellTable = (fragment, schema) => {
|
|
171
|
+
return fragment.childCount === 1 && fragment.firstChild !== null && isNodeSingleCellTable(fragment.firstChild, schema);
|
|
172
|
+
};
|
|
173
|
+
const containsTextBlockChildren = (fragment, schema) => {
|
|
174
|
+
let containsTextBlock = false;
|
|
175
|
+
fragment.forEach(node => {
|
|
176
|
+
if (node.isTextblock) {
|
|
177
|
+
containsTextBlock = true;
|
|
178
|
+
}
|
|
179
|
+
});
|
|
180
|
+
return containsTextBlock;
|
|
181
|
+
};
|
|
166
182
|
export const transformSliceToRemoveOpenTable = (slice, schema) => {
|
|
167
|
-
var _slice$content$
|
|
168
|
-
|
|
169
|
-
|
|
183
|
+
var _slice$content$firstC8;
|
|
184
|
+
if (fg('platform_editor_nested_tables_paste_wrap_fix')) {
|
|
185
|
+
// Case 1: A slice of a textblock selection inside a nested table
|
|
186
|
+
// Prosemirror wraps nested textblock selections in their respective tables
|
|
187
|
+
// We are using `safeInsert` to paste nested tables, so we do not want to preserve this wrapping
|
|
188
|
+
|
|
189
|
+
// slice starts and ends inside a nested table at the same depth
|
|
190
|
+
if (slice.openStart >= 7 && slice.openEnd >= 7 && slice.openStart === slice.openEnd) {
|
|
191
|
+
let cleaned = slice;
|
|
192
|
+
let descendedDepth = 0;
|
|
193
|
+
const tableDepthDecrement = 2;
|
|
170
194
|
|
|
171
|
-
|
|
195
|
+
// if the slice is a single cell table and contains cells with single cell tables, descend into it until we find textblock children
|
|
196
|
+
if (isFragmentSingleCellTable(slice.content, schema)) {
|
|
197
|
+
var _slice$content$firstC2;
|
|
198
|
+
(_slice$content$firstC2 = slice.content.firstChild) === null || _slice$content$firstC2 === void 0 ? void 0 : _slice$content$firstC2.descendants((node, _pos, parent) => {
|
|
199
|
+
if (isNodeSingleCellTable(node, schema)) {
|
|
200
|
+
descendedDepth += tableDepthDecrement;
|
|
201
|
+
} else if (node.type === schema.nodes.table) {
|
|
202
|
+
return false;
|
|
203
|
+
} else if (containsTextBlockChildren(node.content, schema)) {
|
|
204
|
+
descendedDepth += tableDepthDecrement;
|
|
205
|
+
// create a new slice with the content of the textblock children and the depth of the nested tables subtracted
|
|
206
|
+
cleaned = new Slice(node.content, slice.openStart - descendedDepth - tableDepthDecrement, slice.openEnd - descendedDepth - tableDepthDecrement);
|
|
207
|
+
return false;
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
if (!cleaned.eq(slice)) {
|
|
212
|
+
return cleaned;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// Case 2: A slice entirely within a single CELL
|
|
172
218
|
if (
|
|
173
219
|
// starts and ends inside of a cell
|
|
174
220
|
slice.openStart >= 4 && slice.openEnd >= 4 &&
|
|
@@ -177,25 +223,28 @@ export const transformSliceToRemoveOpenTable = (slice, schema) => {
|
|
|
177
223
|
// Ignored via go/ees005
|
|
178
224
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
179
225
|
slice.content.firstChild.type === schema.nodes.table) {
|
|
180
|
-
var _slice$content$
|
|
226
|
+
var _slice$content$firstC3, _slice$content$firstC4, _slice$content$firstC5, _slice$content$firstC6, _slice$content$firstC7;
|
|
227
|
+
// we're removing the table, tableRow and tableCell reducing the open depth by 3
|
|
228
|
+
const depthDecrement = 3;
|
|
229
|
+
|
|
181
230
|
// prosemirror-view has a bug that it duplicates table entry when selecting multiple paragraphs in a table cell.
|
|
182
231
|
// https://github.com/ProseMirror/prosemirror/issues/1270
|
|
183
232
|
// The structure becomes
|
|
184
233
|
// table(genuine) > tableRow(genuine) > table(duplicated) > tableRow(duplicated) > tableCell/tableHeader(genuine) > contents(genuine)
|
|
185
234
|
// As we are removing wrapping table anyway, we keep duplicated table and tableRow for simplicity
|
|
186
235
|
let cleaned = slice;
|
|
187
|
-
if (((_slice$content$
|
|
236
|
+
if (((_slice$content$firstC3 = slice.content.firstChild) === null || _slice$content$firstC3 === void 0 ? void 0 : (_slice$content$firstC4 = _slice$content$firstC3.content) === null || _slice$content$firstC4 === void 0 ? void 0 : (_slice$content$firstC5 = _slice$content$firstC4.firstChild) === null || _slice$content$firstC5 === void 0 ? void 0 : (_slice$content$firstC6 = _slice$content$firstC5.content) === null || _slice$content$firstC6 === void 0 ? void 0 : (_slice$content$firstC7 = _slice$content$firstC6.firstChild) === null || _slice$content$firstC7 === void 0 ? void 0 : _slice$content$firstC7.type) === schema.nodes.table) {
|
|
188
237
|
cleaned = new Slice(slice.content.firstChild.content.firstChild.content, slice.openStart - 2, slice.openEnd - 2);
|
|
189
238
|
}
|
|
190
239
|
return new Slice(flatmap(cleaned.content, unwrapContentFromTable), cleaned.openStart - depthDecrement, cleaned.openEnd - depthDecrement);
|
|
191
240
|
}
|
|
192
241
|
|
|
193
|
-
// Case
|
|
242
|
+
// Case 3: A slice starting within a CELL and ending outside the table
|
|
194
243
|
if (
|
|
195
244
|
// starts inside of a cell but ends outside of the starting table
|
|
196
245
|
slice.openStart >= 4 &&
|
|
197
246
|
// slice starts from a table node (and spans across more than one node)
|
|
198
|
-
slice.content.childCount > 1 && ((_slice$content$
|
|
247
|
+
slice.content.childCount > 1 && ((_slice$content$firstC8 = slice.content.firstChild) === null || _slice$content$firstC8 === void 0 ? void 0 : _slice$content$firstC8.type) === schema.nodes.table) {
|
|
199
248
|
// repoint the slice's cutting depth so that cell content where the slice starts
|
|
200
249
|
// does not get lifted out of the cell on paste
|
|
201
250
|
return new Slice(slice.content, 1, slice.openEnd);
|
|
@@ -165,12 +165,58 @@ export var transformSliceToFixHardBreakProblemOnCopyFromCell = function transfor
|
|
|
165
165
|
}
|
|
166
166
|
return slice;
|
|
167
167
|
};
|
|
168
|
+
var isNodeSingleCellTable = function isNodeSingleCellTable(node, schema) {
|
|
169
|
+
var _node$firstChild, _node$firstChild$firs, _node$firstChild$firs2;
|
|
170
|
+
return node.childCount === 1 && ((_node$firstChild = node.firstChild) === null || _node$firstChild === void 0 ? void 0 : _node$firstChild.type) === schema.nodes.tableRow && node.firstChild.childCount === 1 && (((_node$firstChild$firs = node.firstChild.firstChild) === null || _node$firstChild$firs === void 0 ? void 0 : _node$firstChild$firs.type) === schema.nodes.tableCell || ((_node$firstChild$firs2 = node.firstChild.firstChild) === null || _node$firstChild$firs2 === void 0 ? void 0 : _node$firstChild$firs2.type) === schema.nodes.tableHeader);
|
|
171
|
+
};
|
|
172
|
+
var isFragmentSingleCellTable = function isFragmentSingleCellTable(fragment, schema) {
|
|
173
|
+
return fragment.childCount === 1 && fragment.firstChild !== null && isNodeSingleCellTable(fragment.firstChild, schema);
|
|
174
|
+
};
|
|
175
|
+
var containsTextBlockChildren = function containsTextBlockChildren(fragment, schema) {
|
|
176
|
+
var containsTextBlock = false;
|
|
177
|
+
fragment.forEach(function (node) {
|
|
178
|
+
if (node.isTextblock) {
|
|
179
|
+
containsTextBlock = true;
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
return containsTextBlock;
|
|
183
|
+
};
|
|
168
184
|
export var transformSliceToRemoveOpenTable = function transformSliceToRemoveOpenTable(slice, schema) {
|
|
169
|
-
var _slice$content$
|
|
170
|
-
|
|
171
|
-
|
|
185
|
+
var _slice$content$firstC4;
|
|
186
|
+
if (fg('platform_editor_nested_tables_paste_wrap_fix')) {
|
|
187
|
+
// Case 1: A slice of a textblock selection inside a nested table
|
|
188
|
+
// Prosemirror wraps nested textblock selections in their respective tables
|
|
189
|
+
// We are using `safeInsert` to paste nested tables, so we do not want to preserve this wrapping
|
|
190
|
+
|
|
191
|
+
// slice starts and ends inside a nested table at the same depth
|
|
192
|
+
if (slice.openStart >= 7 && slice.openEnd >= 7 && slice.openStart === slice.openEnd) {
|
|
193
|
+
var cleaned = slice;
|
|
194
|
+
var descendedDepth = 0;
|
|
195
|
+
var tableDepthDecrement = 2;
|
|
172
196
|
|
|
173
|
-
|
|
197
|
+
// if the slice is a single cell table and contains cells with single cell tables, descend into it until we find textblock children
|
|
198
|
+
if (isFragmentSingleCellTable(slice.content, schema)) {
|
|
199
|
+
var _slice$content$firstC2;
|
|
200
|
+
(_slice$content$firstC2 = slice.content.firstChild) === null || _slice$content$firstC2 === void 0 || _slice$content$firstC2.descendants(function (node, _pos, parent) {
|
|
201
|
+
if (isNodeSingleCellTable(node, schema)) {
|
|
202
|
+
descendedDepth += tableDepthDecrement;
|
|
203
|
+
} else if (node.type === schema.nodes.table) {
|
|
204
|
+
return false;
|
|
205
|
+
} else if (containsTextBlockChildren(node.content, schema)) {
|
|
206
|
+
descendedDepth += tableDepthDecrement;
|
|
207
|
+
// create a new slice with the content of the textblock children and the depth of the nested tables subtracted
|
|
208
|
+
cleaned = new Slice(node.content, slice.openStart - descendedDepth - tableDepthDecrement, slice.openEnd - descendedDepth - tableDepthDecrement);
|
|
209
|
+
return false;
|
|
210
|
+
}
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
if (!cleaned.eq(slice)) {
|
|
214
|
+
return cleaned;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// Case 2: A slice entirely within a single CELL
|
|
174
220
|
if (
|
|
175
221
|
// starts and ends inside of a cell
|
|
176
222
|
slice.openStart >= 4 && slice.openEnd >= 4 &&
|
|
@@ -179,25 +225,28 @@ export var transformSliceToRemoveOpenTable = function transformSliceToRemoveOpen
|
|
|
179
225
|
// Ignored via go/ees005
|
|
180
226
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
181
227
|
slice.content.firstChild.type === schema.nodes.table) {
|
|
182
|
-
var _slice$content$
|
|
228
|
+
var _slice$content$firstC3;
|
|
229
|
+
// we're removing the table, tableRow and tableCell reducing the open depth by 3
|
|
230
|
+
var depthDecrement = 3;
|
|
231
|
+
|
|
183
232
|
// prosemirror-view has a bug that it duplicates table entry when selecting multiple paragraphs in a table cell.
|
|
184
233
|
// https://github.com/ProseMirror/prosemirror/issues/1270
|
|
185
234
|
// The structure becomes
|
|
186
235
|
// table(genuine) > tableRow(genuine) > table(duplicated) > tableRow(duplicated) > tableCell/tableHeader(genuine) > contents(genuine)
|
|
187
236
|
// As we are removing wrapping table anyway, we keep duplicated table and tableRow for simplicity
|
|
188
|
-
var
|
|
189
|
-
if (((_slice$content$
|
|
190
|
-
|
|
237
|
+
var _cleaned = slice;
|
|
238
|
+
if (((_slice$content$firstC3 = slice.content.firstChild) === null || _slice$content$firstC3 === void 0 || (_slice$content$firstC3 = _slice$content$firstC3.content) === null || _slice$content$firstC3 === void 0 || (_slice$content$firstC3 = _slice$content$firstC3.firstChild) === null || _slice$content$firstC3 === void 0 || (_slice$content$firstC3 = _slice$content$firstC3.content) === null || _slice$content$firstC3 === void 0 || (_slice$content$firstC3 = _slice$content$firstC3.firstChild) === null || _slice$content$firstC3 === void 0 ? void 0 : _slice$content$firstC3.type) === schema.nodes.table) {
|
|
239
|
+
_cleaned = new Slice(slice.content.firstChild.content.firstChild.content, slice.openStart - 2, slice.openEnd - 2);
|
|
191
240
|
}
|
|
192
|
-
return new Slice(flatmap(
|
|
241
|
+
return new Slice(flatmap(_cleaned.content, unwrapContentFromTable), _cleaned.openStart - depthDecrement, _cleaned.openEnd - depthDecrement);
|
|
193
242
|
}
|
|
194
243
|
|
|
195
|
-
// Case
|
|
244
|
+
// Case 3: A slice starting within a CELL and ending outside the table
|
|
196
245
|
if (
|
|
197
246
|
// starts inside of a cell but ends outside of the starting table
|
|
198
247
|
slice.openStart >= 4 &&
|
|
199
248
|
// slice starts from a table node (and spans across more than one node)
|
|
200
|
-
slice.content.childCount > 1 && ((_slice$content$
|
|
249
|
+
slice.content.childCount > 1 && ((_slice$content$firstC4 = slice.content.firstChild) === null || _slice$content$firstC4 === void 0 ? void 0 : _slice$content$firstC4.type) === schema.nodes.table) {
|
|
201
250
|
// repoint the slice's cutting depth so that cell content where the slice starts
|
|
202
251
|
// does not get lifted out of the cell on paste
|
|
203
252
|
return new Slice(slice.content, 1, slice.openEnd);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-plugin-table",
|
|
3
|
-
"version": "9.3.
|
|
3
|
+
"version": "9.3.5",
|
|
4
4
|
"description": "Table plugin for the @atlaskit/editor",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"registry": "https://registry.npmjs.org/"
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"@atlaskit/adf-schema": "^46.1.0",
|
|
31
31
|
"@atlaskit/button": "^20.5.0",
|
|
32
32
|
"@atlaskit/custom-steps": "^0.9.0",
|
|
33
|
-
"@atlaskit/editor-common": "^99.
|
|
33
|
+
"@atlaskit/editor-common": "^99.9.0",
|
|
34
34
|
"@atlaskit/editor-palette": "1.7.0",
|
|
35
35
|
"@atlaskit/editor-plugin-accessibility-utils": "^1.3.0",
|
|
36
36
|
"@atlaskit/editor-plugin-analytics": "^1.11.0",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"@atlaskit/editor-prosemirror": "6.2.1",
|
|
44
44
|
"@atlaskit/editor-shared-styles": "^3.2.0",
|
|
45
45
|
"@atlaskit/editor-tables": "^2.8.0",
|
|
46
|
-
"@atlaskit/icon": "^23.
|
|
46
|
+
"@atlaskit/icon": "^23.7.0",
|
|
47
47
|
"@atlaskit/menu": "^2.14.0",
|
|
48
48
|
"@atlaskit/platform-feature-flags": "^1.0.0",
|
|
49
49
|
"@atlaskit/pragmatic-drag-and-drop": "^1.5.0",
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"@atlaskit/pragmatic-drag-and-drop-hitbox": "^1.0.0",
|
|
52
52
|
"@atlaskit/primitives": "^13.4.0",
|
|
53
53
|
"@atlaskit/theme": "^14.1.0",
|
|
54
|
-
"@atlaskit/tmp-editor-statsig": "^2.
|
|
54
|
+
"@atlaskit/tmp-editor-statsig": "^2.43.0",
|
|
55
55
|
"@atlaskit/toggle": "^14.1.0",
|
|
56
56
|
"@atlaskit/tokens": "^3.3.0",
|
|
57
57
|
"@atlaskit/tooltip": "^19.1.0",
|
|
@@ -144,6 +144,9 @@
|
|
|
144
144
|
"platform_editor_nested_tables_resizing": {
|
|
145
145
|
"type": "boolean"
|
|
146
146
|
},
|
|
147
|
+
"platform_editor_nested_tables_paste_wrap_fix": {
|
|
148
|
+
"type": "boolean"
|
|
149
|
+
},
|
|
147
150
|
"platform_editor_table_layout_shift_fix": {
|
|
148
151
|
"type": "boolean"
|
|
149
152
|
}
|
package/src/nodeviews/toDOM.ts
CHANGED
|
@@ -145,7 +145,9 @@ export const tableNodeSpecWithFixedToDOM = (config: Config): NodeSpec => {
|
|
|
145
145
|
'--ak-editor-table-min-width': `${tableMinWidth}px`,
|
|
146
146
|
minWidth: 'var(--ak-editor-table-min-width)',
|
|
147
147
|
maxWidth: `min(calc(100cqw - var(--ak-editor-table-gutter-padding)), var(--ak-editor-table-max-width))`,
|
|
148
|
-
width: fg('platform_editor_table_layout_shift_fix')
|
|
148
|
+
width: fg('platform_editor_table_layout_shift_fix')
|
|
149
|
+
? `min(calc(100cqw - var(--ak-editor-table-gutter-padding)), ${node.attrs.width}px)`
|
|
150
|
+
: `min(calc(100cqw - var(--ak-editor-table-gutter-padding)), ${node.attrs.width})`,
|
|
149
151
|
}),
|
|
150
152
|
},
|
|
151
153
|
[
|
|
@@ -211,11 +211,75 @@ export const transformSliceToFixHardBreakProblemOnCopyFromCell = (
|
|
|
211
211
|
return slice;
|
|
212
212
|
};
|
|
213
213
|
|
|
214
|
+
const isNodeSingleCellTable = (node: PMNode, schema: Schema): boolean => {
|
|
215
|
+
return (
|
|
216
|
+
node.childCount === 1 &&
|
|
217
|
+
node.firstChild?.type === schema.nodes.tableRow &&
|
|
218
|
+
node.firstChild.childCount === 1 &&
|
|
219
|
+
(node.firstChild.firstChild?.type === schema.nodes.tableCell ||
|
|
220
|
+
node.firstChild.firstChild?.type === schema.nodes.tableHeader)
|
|
221
|
+
);
|
|
222
|
+
};
|
|
223
|
+
|
|
224
|
+
const isFragmentSingleCellTable = (fragment: Fragment, schema: Schema): boolean => {
|
|
225
|
+
return (
|
|
226
|
+
fragment.childCount === 1 &&
|
|
227
|
+
fragment.firstChild !== null &&
|
|
228
|
+
isNodeSingleCellTable(fragment.firstChild, schema)
|
|
229
|
+
);
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
const containsTextBlockChildren = (fragment: Fragment, schema: Schema): boolean => {
|
|
233
|
+
let containsTextBlock = false;
|
|
234
|
+
|
|
235
|
+
fragment.forEach((node) => {
|
|
236
|
+
if (node.isTextblock) {
|
|
237
|
+
containsTextBlock = true;
|
|
238
|
+
}
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
return containsTextBlock;
|
|
242
|
+
};
|
|
243
|
+
|
|
214
244
|
export const transformSliceToRemoveOpenTable = (slice: Slice, schema: Schema): Slice => {
|
|
215
|
-
|
|
216
|
-
|
|
245
|
+
if (fg('platform_editor_nested_tables_paste_wrap_fix')) {
|
|
246
|
+
// Case 1: A slice of a textblock selection inside a nested table
|
|
247
|
+
// Prosemirror wraps nested textblock selections in their respective tables
|
|
248
|
+
// We are using `safeInsert` to paste nested tables, so we do not want to preserve this wrapping
|
|
249
|
+
|
|
250
|
+
// slice starts and ends inside a nested table at the same depth
|
|
251
|
+
if (slice.openStart >= 7 && slice.openEnd >= 7 && slice.openStart === slice.openEnd) {
|
|
252
|
+
let cleaned = slice;
|
|
253
|
+
let descendedDepth = 0;
|
|
254
|
+
const tableDepthDecrement = 2;
|
|
255
|
+
|
|
256
|
+
// if the slice is a single cell table and contains cells with single cell tables, descend into it until we find textblock children
|
|
257
|
+
if (isFragmentSingleCellTable(slice.content, schema)) {
|
|
258
|
+
slice.content.firstChild?.descendants((node, _pos, parent) => {
|
|
259
|
+
if (isNodeSingleCellTable(node, schema)) {
|
|
260
|
+
descendedDepth += tableDepthDecrement;
|
|
261
|
+
} else if (node.type === schema.nodes.table) {
|
|
262
|
+
return false;
|
|
263
|
+
} else if (containsTextBlockChildren(node.content, schema)) {
|
|
264
|
+
descendedDepth += tableDepthDecrement;
|
|
265
|
+
// create a new slice with the content of the textblock children and the depth of the nested tables subtracted
|
|
266
|
+
cleaned = new Slice(
|
|
267
|
+
node.content,
|
|
268
|
+
slice.openStart - descendedDepth - tableDepthDecrement,
|
|
269
|
+
slice.openEnd - descendedDepth - tableDepthDecrement,
|
|
270
|
+
);
|
|
271
|
+
return false;
|
|
272
|
+
}
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
if (!cleaned.eq(slice)) {
|
|
277
|
+
return cleaned;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}
|
|
217
281
|
|
|
218
|
-
// Case
|
|
282
|
+
// Case 2: A slice entirely within a single CELL
|
|
219
283
|
if (
|
|
220
284
|
// starts and ends inside of a cell
|
|
221
285
|
slice.openStart >= 4 &&
|
|
@@ -226,6 +290,9 @@ export const transformSliceToRemoveOpenTable = (slice: Slice, schema: Schema): S
|
|
|
226
290
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
227
291
|
slice.content.firstChild!.type === schema.nodes.table
|
|
228
292
|
) {
|
|
293
|
+
// we're removing the table, tableRow and tableCell reducing the open depth by 3
|
|
294
|
+
const depthDecrement = 3;
|
|
295
|
+
|
|
229
296
|
// prosemirror-view has a bug that it duplicates table entry when selecting multiple paragraphs in a table cell.
|
|
230
297
|
// https://github.com/ProseMirror/prosemirror/issues/1270
|
|
231
298
|
// The structure becomes
|
|
@@ -250,7 +317,7 @@ export const transformSliceToRemoveOpenTable = (slice: Slice, schema: Schema): S
|
|
|
250
317
|
);
|
|
251
318
|
}
|
|
252
319
|
|
|
253
|
-
// Case
|
|
320
|
+
// Case 3: A slice starting within a CELL and ending outside the table
|
|
254
321
|
if (
|
|
255
322
|
// starts inside of a cell but ends outside of the starting table
|
|
256
323
|
slice.openStart >= 4 &&
|