@atlaskit/editor-plugin-table 1.2.1 → 1.2.2
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 +9 -0
- package/dist/cjs/i18n/en.js +43 -0
- package/dist/cjs/i18n/en_GB.js +43 -0
- package/dist/cjs/plugins/table/nodeviews/OverflowShadowsObserver.js +13 -26
- package/dist/cjs/plugins/table/nodeviews/TableComponent.js +17 -1
- package/dist/cjs/plugins/table/nodeviews/table.js +7 -0
- package/dist/cjs/plugins/table/transforms/delete-rows.js +1 -1
- package/dist/cjs/plugins/table/transforms/index.js +3 -3
- package/dist/cjs/plugins/table/transforms/merge.js +39 -54
- package/dist/cjs/plugins/table/ui/common-styles.js +2 -2
- package/dist/cjs/plugins/table/utils/row-controls.js +3 -2
- package/dist/cjs/version.json +1 -1
- package/dist/es2019/i18n/en.js +36 -0
- package/dist/es2019/i18n/en_GB.js +36 -0
- package/dist/es2019/plugins/table/nodeviews/OverflowShadowsObserver.js +13 -26
- package/dist/es2019/plugins/table/nodeviews/TableComponent.js +21 -1
- package/dist/es2019/plugins/table/nodeviews/table.js +7 -0
- package/dist/es2019/plugins/table/transforms/delete-rows.js +2 -2
- package/dist/es2019/plugins/table/transforms/index.js +1 -1
- package/dist/es2019/plugins/table/transforms/merge.js +39 -43
- package/dist/es2019/plugins/table/ui/common-styles.js +20 -1
- package/dist/es2019/plugins/table/utils/row-controls.js +3 -2
- package/dist/es2019/version.json +1 -1
- package/dist/esm/i18n/en.js +36 -0
- package/dist/esm/i18n/en_GB.js +36 -0
- package/dist/esm/plugins/table/nodeviews/OverflowShadowsObserver.js +13 -26
- package/dist/esm/plugins/table/nodeviews/TableComponent.js +17 -1
- package/dist/esm/plugins/table/nodeviews/table.js +7 -0
- package/dist/esm/plugins/table/transforms/delete-rows.js +2 -2
- package/dist/esm/plugins/table/transforms/index.js +1 -1
- package/dist/esm/plugins/table/transforms/merge.js +38 -53
- package/dist/esm/plugins/table/ui/common-styles.js +2 -2
- package/dist/esm/plugins/table/utils/row-controls.js +3 -2
- package/dist/esm/version.json +1 -1
- package/dist/types/i18n/en.d.ts +35 -0
- package/dist/types/i18n/en_GB.d.ts +35 -0
- package/dist/types/plugins/table/nodeviews/OverflowShadowsObserver.d.ts +4 -5
- package/dist/types/plugins/table/nodeviews/TableComponent.d.ts +1 -0
- package/dist/types/plugins/table/nodeviews/__mocks__/OverflowShadowsObserver.d.ts +3 -3
- package/dist/types/plugins/table/transforms/index.d.ts +1 -1
- package/dist/types/plugins/table/transforms/merge.d.ts +1 -1
- package/dist/types/plugins/table/types.d.ts +2 -0
- package/package.json +7 -6
- package/src/__tests__/integration/__fixtures__/table-and-paragraph-adf.ts +130 -0
- package/src/__tests__/integration/horizontal-scroll-shadows.ts +199 -0
- package/src/__tests__/integration/meta-arrowup-cursor-in-first-row.ts +4 -2
- package/src/__tests__/unit/commands/sort.ts +4 -0
- package/src/__tests__/unit/commands.ts +2 -0
- package/src/__tests__/unit/index.ts +2 -0
- package/src/__tests__/unit/keymap.ts +4 -2
- package/src/__tests__/unit/layout.ts +2 -0
- package/src/__tests__/unit/nodeviews/OverflowShadowsObserver.ts +20 -11
- package/src/__tests__/unit/pm-plugins/main-with-allow-collapse.ts +2 -0
- package/src/__tests__/unit/transforms/delete-rows.ts +45 -0
- package/src/__tests__/unit/utils/collapse.ts +4 -1
- package/src/i18n/en.ts +36 -0
- package/src/i18n/en_GB.ts +36 -0
- package/src/plugins/table/nodeviews/OverflowShadowsObserver.ts +24 -40
- package/src/plugins/table/nodeviews/TableComponent.tsx +19 -2
- package/src/plugins/table/nodeviews/__mocks__/OverflowShadowsObserver.ts +3 -3
- package/src/plugins/table/nodeviews/table.tsx +12 -0
- package/src/plugins/table/transforms/delete-rows.ts +2 -2
- package/src/plugins/table/transforms/index.ts +1 -1
- package/src/plugins/table/transforms/merge.ts +41 -43
- package/src/plugins/table/ui/common-styles.ts +20 -0
- package/src/plugins/table/utils/row-controls.ts +3 -2
- package/src/__tests__/integration/__fixtures__/table-and-paragraph-adf.json +0 -130
|
@@ -225,9 +225,8 @@ class TableComponent extends React.Component<ComponentProps, TableState> {
|
|
|
225
225
|
}
|
|
226
226
|
|
|
227
227
|
if (this.overflowShadowsObserver) {
|
|
228
|
-
this.overflowShadowsObserver.
|
|
228
|
+
this.overflowShadowsObserver.observeShadowSentinels(
|
|
229
229
|
this.state.stickyHeader?.sticky,
|
|
230
|
-
containsHeaderRow(getNode()),
|
|
231
230
|
);
|
|
232
231
|
}
|
|
233
232
|
}
|
|
@@ -287,6 +286,17 @@ class TableComponent extends React.Component<ComponentProps, TableState> {
|
|
|
287
286
|
this.setState({ [shadowKey]: value });
|
|
288
287
|
};
|
|
289
288
|
|
|
289
|
+
private createShadowSentinels = (table: HTMLTableElement | null) => {
|
|
290
|
+
if (table) {
|
|
291
|
+
const shadowSentinelLeft = document.createElement('span');
|
|
292
|
+
shadowSentinelLeft.className = ClassName.TABLE_SHADOW_SENTINEL_LEFT;
|
|
293
|
+
const shadowSentinelRight = document.createElement('span');
|
|
294
|
+
shadowSentinelRight.className = ClassName.TABLE_SHADOW_SENTINEL_RIGHT;
|
|
295
|
+
table.prepend(shadowSentinelLeft);
|
|
296
|
+
table.prepend(shadowSentinelRight);
|
|
297
|
+
}
|
|
298
|
+
};
|
|
299
|
+
|
|
290
300
|
onStickyState = (state: StickyPluginState) => {
|
|
291
301
|
const { tableOverflowShadowsOptimization } =
|
|
292
302
|
this.props.getEditorFeatureFlags();
|
|
@@ -440,6 +450,7 @@ class TableComponent extends React.Component<ComponentProps, TableState> {
|
|
|
440
450
|
const tableElement = elem.querySelector('table');
|
|
441
451
|
if (tableElement !== this.table) {
|
|
442
452
|
this.table = tableElement;
|
|
453
|
+
this.createShadowSentinels(this.table);
|
|
443
454
|
}
|
|
444
455
|
}
|
|
445
456
|
}}
|
|
@@ -519,6 +530,12 @@ class TableComponent extends React.Component<ComponentProps, TableState> {
|
|
|
519
530
|
if (!tableOverflowShadowsOptimization) {
|
|
520
531
|
this.updateShadows();
|
|
521
532
|
}
|
|
533
|
+
|
|
534
|
+
if (this.wrapper.scrollLeft === 0) {
|
|
535
|
+
this.setState({ [ShadowEvent.SHOW_BEFORE_SHADOW]: false });
|
|
536
|
+
} else {
|
|
537
|
+
this.setState({ [ShadowEvent.SHOW_BEFORE_SHADOW]: true });
|
|
538
|
+
}
|
|
522
539
|
};
|
|
523
540
|
|
|
524
541
|
private handleTableResizing = () => {
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { OverridableMock } from './OverridableMock';
|
|
2
2
|
|
|
3
3
|
export class OverflowShadowsObserver extends OverridableMock {
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
leftShadowSentinel: HTMLElement | null = null;
|
|
5
|
+
rightShadowSentinel: HTMLElement | null = null;
|
|
6
6
|
constructor(...inputs: any[]) {
|
|
7
7
|
super(...inputs);
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
observeShadowSentinels = this.getMock('observeShadowSentinels');
|
|
11
11
|
updateStickyShadows = this.getMock('updateStickyShadows');
|
|
12
12
|
dispose = this.getMock('dispose');
|
|
13
13
|
}
|
|
@@ -225,6 +225,18 @@ export default class TableView extends ReactNodeView<Props> {
|
|
|
225
225
|
return false;
|
|
226
226
|
}
|
|
227
227
|
|
|
228
|
+
// ED-16668
|
|
229
|
+
// Do not remove this fixes an issue with windows firefox that relates to
|
|
230
|
+
// the addition of the shadow sentinels
|
|
231
|
+
if (
|
|
232
|
+
type === 'selection' &&
|
|
233
|
+
nodeName?.toUpperCase() === 'TABLE' &&
|
|
234
|
+
(firstChild?.nodeName.toUpperCase() === 'COLGROUP' ||
|
|
235
|
+
firstChild?.nodeName.toUpperCase() === 'SPAN')
|
|
236
|
+
) {
|
|
237
|
+
return false;
|
|
238
|
+
}
|
|
239
|
+
|
|
228
240
|
return true;
|
|
229
241
|
}
|
|
230
242
|
|
|
@@ -5,7 +5,7 @@ import { findTable } from '@atlaskit/editor-tables/utils';
|
|
|
5
5
|
|
|
6
6
|
import { CellAttributes } from '@atlaskit/adf-schema';
|
|
7
7
|
|
|
8
|
-
import {
|
|
8
|
+
import { mergeEmptyColumns } from './merge';
|
|
9
9
|
import { setMeta } from './metadata';
|
|
10
10
|
|
|
11
11
|
export const deleteRows =
|
|
@@ -125,7 +125,7 @@ export const deleteRows =
|
|
|
125
125
|
rows,
|
|
126
126
|
table.node.marks,
|
|
127
127
|
);
|
|
128
|
-
const fixedTable =
|
|
128
|
+
const fixedTable = mergeEmptyColumns(newTable);
|
|
129
129
|
if (fixedTable === null) {
|
|
130
130
|
return setMeta({ type: 'DELETE_ROWS', problem: 'REMOVE_EMPTY_COLUMNS' })(
|
|
131
131
|
tr,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { mergeCells, canMergeCells, removeEmptyColumns } from './merge';
|
|
2
1
|
export { fireAnalytics, fixTables, fixAutoSizedTable } from './fix-tables';
|
|
2
|
+
export { mergeCells, canMergeCells, mergeEmptyColumns } from './merge';
|
|
3
3
|
export { deleteColumns } from './delete-columns';
|
|
4
4
|
export { deleteRows } from './delete-rows';
|
|
5
5
|
export { updateColumnWidths } from './column-width';
|
|
@@ -131,7 +131,8 @@ export function mergeCells(tr: Transaction): Transaction {
|
|
|
131
131
|
rows,
|
|
132
132
|
table.node.marks,
|
|
133
133
|
);
|
|
134
|
-
|
|
134
|
+
|
|
135
|
+
const fixedTable = mergeEmptyColumns(newTable);
|
|
135
136
|
if (fixedTable === null) {
|
|
136
137
|
return setMeta({ type: 'MERGE_CELLS', problem: 'REMOVE_EMPTY_COLUMNS' })(
|
|
137
138
|
tr,
|
|
@@ -227,77 +228,74 @@ function cellsOverlapRectangle({ width, height, map }: TableMap, rect: Rect) {
|
|
|
227
228
|
}
|
|
228
229
|
|
|
229
230
|
// returns an array of numbers, each number indicates the minimum colSpan in each column
|
|
230
|
-
function
|
|
231
|
+
function getEmptyColumnIndexes(table: PMNode): Set<number> {
|
|
231
232
|
const map = TableMap.get(table);
|
|
232
|
-
const
|
|
233
|
-
|
|
234
|
-
|
|
233
|
+
const emptyColumnIndexes = new Set<number>();
|
|
234
|
+
|
|
235
|
+
// Loop throuh each column
|
|
236
|
+
for (let colIndex = 0; colIndex < map.width; colIndex++) {
|
|
237
|
+
// Get the cells in each row for this column
|
|
238
|
+
const cellPositions = map.cellsInRect({
|
|
235
239
|
left: colIndex,
|
|
236
240
|
right: colIndex + 1,
|
|
237
241
|
top: 0,
|
|
238
242
|
bottom: map.height,
|
|
239
243
|
});
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
return cell.attrs.colspan;
|
|
245
|
-
}
|
|
246
|
-
});
|
|
247
|
-
const minColspan = Math.min(...colspans);
|
|
248
|
-
// only care about the case when the next column is invisible
|
|
249
|
-
if (!minColspans[colIndex + 1]) {
|
|
250
|
-
minColspans[colIndex] = minColspan;
|
|
251
|
-
} else {
|
|
252
|
-
minColspans[colIndex] = 1;
|
|
253
|
-
}
|
|
244
|
+
|
|
245
|
+
// If no cells exist in that column it is empty
|
|
246
|
+
if (!cellPositions.length) {
|
|
247
|
+
emptyColumnIndexes.add(colIndex);
|
|
254
248
|
}
|
|
255
249
|
}
|
|
256
250
|
|
|
257
|
-
return
|
|
251
|
+
return emptyColumnIndexes;
|
|
258
252
|
}
|
|
259
253
|
|
|
260
|
-
export function
|
|
254
|
+
export function mergeEmptyColumns(table: PMNode): PMNode | null {
|
|
255
|
+
const rows: PMNode[] = [];
|
|
261
256
|
const map = TableMap.get(table);
|
|
262
|
-
const
|
|
263
|
-
|
|
257
|
+
const emptyColumnIndexes = getEmptyColumnIndexes(table);
|
|
258
|
+
|
|
259
|
+
// We don't need to remove any so return early.
|
|
260
|
+
if (emptyColumnIndexes.size === 0) {
|
|
264
261
|
return table;
|
|
265
262
|
}
|
|
266
|
-
|
|
263
|
+
|
|
267
264
|
for (let rowIndex = 0; rowIndex < map.height; rowIndex++) {
|
|
268
265
|
const cellsByCols: Record<string, PMNode> = {};
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
266
|
+
|
|
267
|
+
// Work backwards so that calculating colwidths is easier with Array.slice
|
|
268
|
+
for (let colIndex = map.width - 1; colIndex >= 0; colIndex--) {
|
|
272
269
|
const cellPos = map.map[colIndex + rowIndex * map.width];
|
|
273
270
|
const rect = map.findCell(cellPos);
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
271
|
+
let cell = cellsByCols[rect.left] || table.nodeAt(cellPos);
|
|
272
|
+
|
|
273
|
+
if (rect.top !== rowIndex) {
|
|
274
|
+
continue;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// If this column is empty, we want to decrement the colspan of its corresponding
|
|
278
|
+
// cell as this column is being "merged"
|
|
279
|
+
if (emptyColumnIndexes.has(colIndex)) {
|
|
280
|
+
const { colspan, colwidth } = cell.attrs;
|
|
281
|
+
|
|
282
|
+
if (colspan > 1) {
|
|
283
|
+
cell = cell.type.createChecked(
|
|
283
284
|
{
|
|
284
285
|
...cell.attrs,
|
|
285
|
-
colspan,
|
|
286
|
+
colspan: colspan - 1,
|
|
286
287
|
colwidth: colwidth ? colwidth.slice(0, colspan) : null,
|
|
287
288
|
},
|
|
288
289
|
cell.content,
|
|
289
290
|
cell.marks,
|
|
290
291
|
);
|
|
291
|
-
cellsByCols[rect.left] = newCell;
|
|
292
|
-
} else {
|
|
293
|
-
cellsByCols[rect.left] = cell;
|
|
294
292
|
}
|
|
295
293
|
}
|
|
294
|
+
|
|
295
|
+
cellsByCols[rect.left] = cell;
|
|
296
296
|
}
|
|
297
297
|
|
|
298
|
-
const rowCells
|
|
299
|
-
(col) => cellsByCols[col],
|
|
300
|
-
);
|
|
298
|
+
const rowCells = Object.values(cellsByCols);
|
|
301
299
|
const row = table.child(rowIndex);
|
|
302
300
|
if (row) {
|
|
303
301
|
rows.push(row.type.createChecked(row.attrs, rowCells, row.marks));
|
|
@@ -113,6 +113,22 @@ const sentinelStyles = `.${ClassName.TABLE_CONTAINER} {
|
|
|
113
113
|
}
|
|
114
114
|
}`;
|
|
115
115
|
|
|
116
|
+
const shadowSentinelStyles = `
|
|
117
|
+
.${ClassName.TABLE_SHADOW_SENTINEL_LEFT},
|
|
118
|
+
.${ClassName.TABLE_SHADOW_SENTINEL_RIGHT} {
|
|
119
|
+
position: absolute;
|
|
120
|
+
top: 0;
|
|
121
|
+
height: 100%;
|
|
122
|
+
width: 1px;
|
|
123
|
+
visibility: hidden;
|
|
124
|
+
}
|
|
125
|
+
.${ClassName.TABLE_SHADOW_SENTINEL_LEFT} {
|
|
126
|
+
left: 0;
|
|
127
|
+
}
|
|
128
|
+
.${ClassName.TABLE_SHADOW_SENTINEL_RIGHT} {
|
|
129
|
+
right: 0;
|
|
130
|
+
}
|
|
131
|
+
`;
|
|
116
132
|
// previous styles to add spacing to numbered lists with
|
|
117
133
|
// large item markers (e.g. 101, 102, ...) when nested inside tables
|
|
118
134
|
const listLargeNumericMarkersOldStyles = `
|
|
@@ -624,6 +640,8 @@ export const tableStyles = (
|
|
|
624
640
|
border-top: none;
|
|
625
641
|
// 1px border width offset added here to prevent unwanted overflow and scolling - ED-16212
|
|
626
642
|
margin-right: -1px;
|
|
643
|
+
// Allows better positioning for the shadow sentinels - ED-16668
|
|
644
|
+
position: relative;
|
|
627
645
|
|
|
628
646
|
> tbody > tr {
|
|
629
647
|
white-space: pre-wrap;
|
|
@@ -741,6 +759,8 @@ export const tableStyles = (
|
|
|
741
759
|
${props?.featureFlags?.restartNumberedLists
|
|
742
760
|
? ``
|
|
743
761
|
: listLargeNumericMarkersOldStyles}
|
|
762
|
+
|
|
763
|
+
${shadowSentinelStyles}
|
|
744
764
|
`;
|
|
745
765
|
|
|
746
766
|
export const tableFullPageEditorStyles = css`
|
|
@@ -22,8 +22,9 @@ export interface RowParams {
|
|
|
22
22
|
|
|
23
23
|
export const getRowHeights = (tableRef: HTMLTableElement): number[] => {
|
|
24
24
|
const heights: number[] = [];
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
const tableBody = tableRef.querySelector('tbody');
|
|
26
|
+
if (tableBody) {
|
|
27
|
+
const rows = tableBody.childNodes;
|
|
27
28
|
for (let i = 0, count = rows.length; i < count; i++) {
|
|
28
29
|
const row = rows[i] as HTMLTableRowElement;
|
|
29
30
|
heights[i] = row.getBoundingClientRect().height + 1;
|
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 1,
|
|
3
|
-
"type": "doc",
|
|
4
|
-
"content": [
|
|
5
|
-
{
|
|
6
|
-
"type": "table",
|
|
7
|
-
"attrs": {
|
|
8
|
-
"isNumberColumnEnabled": false,
|
|
9
|
-
"layout": "default",
|
|
10
|
-
"localId": "e1365400-6226-4bb9-b3f1-b80fd3ae640a"
|
|
11
|
-
},
|
|
12
|
-
"content": [
|
|
13
|
-
{
|
|
14
|
-
"type": "tableRow",
|
|
15
|
-
"content": [
|
|
16
|
-
{
|
|
17
|
-
"type": "tableHeader",
|
|
18
|
-
"attrs": {},
|
|
19
|
-
"content": [
|
|
20
|
-
{
|
|
21
|
-
"type": "paragraph",
|
|
22
|
-
"content": []
|
|
23
|
-
}
|
|
24
|
-
]
|
|
25
|
-
},
|
|
26
|
-
{
|
|
27
|
-
"type": "tableHeader",
|
|
28
|
-
"attrs": {},
|
|
29
|
-
"content": [
|
|
30
|
-
{
|
|
31
|
-
"type": "paragraph",
|
|
32
|
-
"content": []
|
|
33
|
-
}
|
|
34
|
-
]
|
|
35
|
-
},
|
|
36
|
-
{
|
|
37
|
-
"type": "tableHeader",
|
|
38
|
-
"attrs": {},
|
|
39
|
-
"content": [
|
|
40
|
-
{
|
|
41
|
-
"type": "paragraph",
|
|
42
|
-
"content": []
|
|
43
|
-
}
|
|
44
|
-
]
|
|
45
|
-
}
|
|
46
|
-
]
|
|
47
|
-
},
|
|
48
|
-
{
|
|
49
|
-
"type": "tableRow",
|
|
50
|
-
"content": [
|
|
51
|
-
{
|
|
52
|
-
"type": "tableCell",
|
|
53
|
-
"attrs": {},
|
|
54
|
-
"content": [
|
|
55
|
-
{
|
|
56
|
-
"type": "paragraph",
|
|
57
|
-
"content": []
|
|
58
|
-
}
|
|
59
|
-
]
|
|
60
|
-
},
|
|
61
|
-
{
|
|
62
|
-
"type": "tableCell",
|
|
63
|
-
"attrs": {},
|
|
64
|
-
"content": [
|
|
65
|
-
{
|
|
66
|
-
"type": "paragraph",
|
|
67
|
-
"content": []
|
|
68
|
-
}
|
|
69
|
-
]
|
|
70
|
-
},
|
|
71
|
-
{
|
|
72
|
-
"type": "tableCell",
|
|
73
|
-
"attrs": {},
|
|
74
|
-
"content": [
|
|
75
|
-
{
|
|
76
|
-
"type": "paragraph",
|
|
77
|
-
"content": []
|
|
78
|
-
}
|
|
79
|
-
]
|
|
80
|
-
}
|
|
81
|
-
]
|
|
82
|
-
},
|
|
83
|
-
{
|
|
84
|
-
"type": "tableRow",
|
|
85
|
-
"content": [
|
|
86
|
-
{
|
|
87
|
-
"type": "tableCell",
|
|
88
|
-
"attrs": {},
|
|
89
|
-
"content": [
|
|
90
|
-
{
|
|
91
|
-
"type": "paragraph",
|
|
92
|
-
"content": []
|
|
93
|
-
}
|
|
94
|
-
]
|
|
95
|
-
},
|
|
96
|
-
{
|
|
97
|
-
"type": "tableCell",
|
|
98
|
-
"attrs": {},
|
|
99
|
-
"content": [
|
|
100
|
-
{
|
|
101
|
-
"type": "paragraph",
|
|
102
|
-
"content": []
|
|
103
|
-
}
|
|
104
|
-
]
|
|
105
|
-
},
|
|
106
|
-
{
|
|
107
|
-
"type": "tableCell",
|
|
108
|
-
"attrs": {},
|
|
109
|
-
"content": [
|
|
110
|
-
{
|
|
111
|
-
"type": "paragraph",
|
|
112
|
-
"content": []
|
|
113
|
-
}
|
|
114
|
-
]
|
|
115
|
-
}
|
|
116
|
-
]
|
|
117
|
-
}
|
|
118
|
-
]
|
|
119
|
-
},
|
|
120
|
-
{
|
|
121
|
-
"type": "paragraph",
|
|
122
|
-
"content": [
|
|
123
|
-
{
|
|
124
|
-
"type": "text",
|
|
125
|
-
"text": "text"
|
|
126
|
-
}
|
|
127
|
-
]
|
|
128
|
-
}
|
|
129
|
-
]
|
|
130
|
-
}
|