PluginProbe
Tableberg – Simple Gutenberg Table Block / 1.2.0
Tableberg – Simple Gutenberg Table Block v1.2.0
1.2.0 1.1.5 1.1.4 1.1.3 1.1.2 1.1.1 1.1.0 1.0.5 1.0.4 1.0.3 1.0.2 1.0.1 trunk 0.0.2 0.2.1 0.3.2 0.3.3 0.4.1 0.5.0 0.5.1 0.5.2 0.5.3 0.5.4 0.5.5 0.5.6 All 43 releases
tableberg / src / migrate / blocks-to-attrs.ts

blocks-to-attrs.ts in Tableberg – Simple Gutenberg Table Block 1.2.0, at src/migrate/blocks-to-attrs.ts

116 lines 3.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import { BlockInstance } from "@wordpress/blocks";
2
3 import {
4 Cell,
5 CellElement,
6 CellKey,
7 RowConfigs,
8 TablebergBlockAttrs,
9 } from "../attributes";
10
11 /**
12 * JS mirror of renderer/Table/InnerBlocksAttrsAdapter.php: reduces the v4
13 * native block tree (rows -> cells -> elements) to the v3 cells/rows shape.
14 * Used to snapshot the tree into the table store so the existing preview UI
15 * (sorting/search/pagination/responsive via PrimaryTable) renders from it.
16 */
17 export function blocksToV3Content(rowBlocks: BlockInstance[]): {
18 cells: Record<CellKey, Cell>;
19 rows: RowConfigs;
20 rowsCount: number;
21 colsCount: number;
22 /** Grid position -> cell block clientId (for targeted write-backs). */
23 cellClientIds: Record<CellKey, string>;
24 } {
25 const cells: Record<CellKey, Cell> = {};
26 const cellClientIds: Record<CellKey, string> = {};
27 const rows: RowConfigs = [];
28 const covered = new Set<string>();
29 let colsCount = 0;
30
31 let row = 0;
32 for (const rowBlock of rowBlocks) {
33 if (rowBlock.name !== "tableberg/row") {
34 continue;
35 }
36
37 const rowAttrs = rowBlock.attributes ?? {};
38 rows[row] =
39 Object.keys(rowAttrs).length > 0
40 ? ({ ...rowAttrs } as RowConfigs[number])
41 : null;
42
43 let col = 0;
44 for (const cellBlock of rowBlock.innerBlocks) {
45 if (cellBlock.name !== "tableberg/cell") {
46 continue;
47 }
48
49 while (covered.has(`${row},${col}`)) {
50 col++;
51 }
52
53 const attrs = cellBlock.attributes ?? {};
54 // Keep the reverse adapter symmetric with v3-to-v4: all block
55 // attributes pass through, while elements come from innerBlocks.
56 const cell: Cell = { ...attrs } as Cell;
57 cell.elements = blocksToElements(cellBlock.innerBlocks);
58
59 cells[`${row},${col}` as CellKey] = cell;
60 cellClientIds[`${row},${col}` as CellKey] = cellBlock.clientId;
61
62 const rowSpan = Math.max(1, attrs.span?.rowSpan ?? 1);
63 const colSpan = Math.max(1, attrs.span?.colSpan ?? 1);
64 for (let dr = 0; dr < rowSpan; dr++) {
65 for (let dc = 0; dc < colSpan; dc++) {
66 if (dr === 0 && dc === 0) {
67 continue;
68 }
69 covered.add(`${row + dr},${col + dc}`);
70 }
71 }
72
73 col += colSpan;
74 if (col > colsCount) {
75 colsCount = col;
76 }
77 }
78
79 while (covered.has(`${row},${col}`)) {
80 col++;
81 if (col > colsCount) {
82 colsCount = col;
83 }
84 }
85
86 row++;
87 }
88
89 return { cells, rows, rowsCount: row, colsCount, cellClientIds };
90 }
91
92 function blocksToElements(elementBlocks: BlockInstance[]): CellElement[] {
93 const elements: CellElement[] = [];
94
95 for (const block of elementBlocks) {
96 if (!block.name.startsWith("tableberg/")) {
97 continue;
98 }
99
100 const name = block.name.slice("tableberg/".length);
101 const { bindings, ...attributes } = block.attributes ?? {};
102
103 const element = {
104 name,
105 attributes,
106 } as CellElement;
107 if (bindings && Object.keys(bindings).length > 0) {
108 element.bindings = bindings;
109 }
110
111 elements.push(element);
112 }
113
114 return elements;
115 }
116