@kerebron/extension-tables 0.0.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/LICENSE +23 -0
- package/README.md +34 -0
- package/assets/tables.css +48 -0
- package/esm/ExtensionTables.d.ts +10 -0
- package/esm/ExtensionTables.d.ts.map +1 -0
- package/esm/ExtensionTables.js +27 -0
- package/esm/NodeTable.d.ts +24 -0
- package/esm/NodeTable.d.ts.map +1 -0
- package/esm/NodeTable.js +115 -0
- package/esm/NodeTableCell.d.ts +16 -0
- package/esm/NodeTableCell.d.ts.map +1 -0
- package/esm/NodeTableCell.js +77 -0
- package/esm/NodeTableHeader.d.ts +16 -0
- package/esm/NodeTableHeader.d.ts.map +1 -0
- package/esm/NodeTableHeader.js +75 -0
- package/esm/NodeTableRow.d.ts +16 -0
- package/esm/NodeTableRow.d.ts.map +1 -0
- package/esm/NodeTableRow.js +47 -0
- package/esm/_dnt.shims.d.ts +6 -0
- package/esm/_dnt.shims.d.ts.map +1 -0
- package/esm/_dnt.shims.js +61 -0
- package/esm/package.json +3 -0
- package/esm/utilities/CellSelection.d.ts +53 -0
- package/esm/utilities/CellSelection.d.ts.map +1 -0
- package/esm/utilities/CellSelection.js +382 -0
- package/esm/utilities/TableMap.d.ts +92 -0
- package/esm/utilities/TableMap.d.ts.map +1 -0
- package/esm/utilities/TableMap.js +335 -0
- package/esm/utilities/TableView.d.ts +21 -0
- package/esm/utilities/TableView.d.ts.map +1 -0
- package/esm/utilities/TableView.js +108 -0
- package/esm/utilities/columnResizing.d.ts +50 -0
- package/esm/utilities/columnResizing.d.ts.map +1 -0
- package/esm/utilities/columnResizing.js +307 -0
- package/esm/utilities/commands.d.ts +166 -0
- package/esm/utilities/commands.d.ts.map +1 -0
- package/esm/utilities/commands.js +702 -0
- package/esm/utilities/copypaste.d.ts +35 -0
- package/esm/utilities/copypaste.d.ts.map +1 -0
- package/esm/utilities/copypaste.js +283 -0
- package/esm/utilities/createCell.d.ts +3 -0
- package/esm/utilities/createCell.d.ts.map +1 -0
- package/esm/utilities/createCell.js +6 -0
- package/esm/utilities/createTable.d.ts +3 -0
- package/esm/utilities/createTable.d.ts.map +1 -0
- package/esm/utilities/createTable.js +30 -0
- package/esm/utilities/fixTables.d.ts +18 -0
- package/esm/utilities/fixTables.d.ts.map +1 -0
- package/esm/utilities/fixTables.js +146 -0
- package/esm/utilities/getTableNodeTypes.d.ts +5 -0
- package/esm/utilities/getTableNodeTypes.d.ts.map +1 -0
- package/esm/utilities/getTableNodeTypes.js +14 -0
- package/esm/utilities/input.d.ts +21 -0
- package/esm/utilities/input.d.ts.map +1 -0
- package/esm/utilities/input.js +241 -0
- package/esm/utilities/tableEditing.d.ts +23 -0
- package/esm/utilities/tableEditing.d.ts.map +1 -0
- package/esm/utilities/tableEditing.js +63 -0
- package/esm/utilities/tableNodeTypes.d.ts +14 -0
- package/esm/utilities/tableNodeTypes.d.ts.map +1 -0
- package/esm/utilities/tableNodeTypes.js +16 -0
- package/esm/utilities/util.d.ts +73 -0
- package/esm/utilities/util.d.ts.map +1 -0
- package/esm/utilities/util.js +155 -0
- package/package.json +30 -0
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
let readFromCache;
|
|
2
|
+
let addToCache;
|
|
3
|
+
// Prefer using a weak map to cache table maps. Fall back on a
|
|
4
|
+
// fixed-size cache if that's not supported.
|
|
5
|
+
if (typeof WeakMap != 'undefined') {
|
|
6
|
+
// eslint-disable-next-line
|
|
7
|
+
const cache = new WeakMap();
|
|
8
|
+
readFromCache = (key) => cache.get(key);
|
|
9
|
+
addToCache = (key, value) => {
|
|
10
|
+
cache.set(key, value);
|
|
11
|
+
return value;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
const cache = [];
|
|
16
|
+
const cacheSize = 10;
|
|
17
|
+
let cachePos = 0;
|
|
18
|
+
readFromCache = (key) => {
|
|
19
|
+
for (let i = 0; i < cache.length; i += 2) {
|
|
20
|
+
if (cache[i] == key)
|
|
21
|
+
return cache[i + 1];
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
addToCache = (key, value) => {
|
|
25
|
+
if (cachePos == cacheSize)
|
|
26
|
+
cachePos = 0;
|
|
27
|
+
cache[cachePos++] = key;
|
|
28
|
+
return (cache[cachePos++] = value);
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* A table map describes the structure of a given table. To avoid
|
|
33
|
+
* recomputing them all the time, they are cached per table node. To
|
|
34
|
+
* be able to do that, positions saved in the map are relative to the
|
|
35
|
+
* start of the table, rather than the start of the document.
|
|
36
|
+
*
|
|
37
|
+
* @public
|
|
38
|
+
*/
|
|
39
|
+
export class TableMap {
|
|
40
|
+
constructor(
|
|
41
|
+
/**
|
|
42
|
+
* The number of columns
|
|
43
|
+
*/
|
|
44
|
+
width,
|
|
45
|
+
/**
|
|
46
|
+
* The number of rows
|
|
47
|
+
*/
|
|
48
|
+
height,
|
|
49
|
+
/**
|
|
50
|
+
* A width * height array with the start position of
|
|
51
|
+
* the cell covering that part of the table in each slot
|
|
52
|
+
*/
|
|
53
|
+
map,
|
|
54
|
+
/**
|
|
55
|
+
* An optional array of problems (cell overlap or non-rectangular
|
|
56
|
+
* shape) for the table, used by the table normalizer.
|
|
57
|
+
*/
|
|
58
|
+
problems) {
|
|
59
|
+
Object.defineProperty(this, "width", {
|
|
60
|
+
enumerable: true,
|
|
61
|
+
configurable: true,
|
|
62
|
+
writable: true,
|
|
63
|
+
value: width
|
|
64
|
+
});
|
|
65
|
+
Object.defineProperty(this, "height", {
|
|
66
|
+
enumerable: true,
|
|
67
|
+
configurable: true,
|
|
68
|
+
writable: true,
|
|
69
|
+
value: height
|
|
70
|
+
});
|
|
71
|
+
Object.defineProperty(this, "map", {
|
|
72
|
+
enumerable: true,
|
|
73
|
+
configurable: true,
|
|
74
|
+
writable: true,
|
|
75
|
+
value: map
|
|
76
|
+
});
|
|
77
|
+
Object.defineProperty(this, "problems", {
|
|
78
|
+
enumerable: true,
|
|
79
|
+
configurable: true,
|
|
80
|
+
writable: true,
|
|
81
|
+
value: problems
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
// Find the dimensions of the cell at the given position.
|
|
85
|
+
findCell(pos) {
|
|
86
|
+
for (let i = 0; i < this.map.length; i++) {
|
|
87
|
+
const curPos = this.map[i];
|
|
88
|
+
if (curPos != pos)
|
|
89
|
+
continue;
|
|
90
|
+
const left = i % this.width;
|
|
91
|
+
const top = (i / this.width) | 0;
|
|
92
|
+
let right = left + 1;
|
|
93
|
+
let bottom = top + 1;
|
|
94
|
+
for (let j = 1; right < this.width && this.map[i + j] == curPos; j++) {
|
|
95
|
+
right++;
|
|
96
|
+
}
|
|
97
|
+
for (let j = 1; bottom < this.height && this.map[i + this.width * j] == curPos; j++) {
|
|
98
|
+
bottom++;
|
|
99
|
+
}
|
|
100
|
+
return { left, top, right, bottom };
|
|
101
|
+
}
|
|
102
|
+
throw new RangeError(`No cell with offset ${pos} found`);
|
|
103
|
+
}
|
|
104
|
+
// Find the left side of the cell at the given position.
|
|
105
|
+
colCount(pos) {
|
|
106
|
+
for (let i = 0; i < this.map.length; i++) {
|
|
107
|
+
if (this.map[i] == pos) {
|
|
108
|
+
return i % this.width;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
throw new RangeError(`No cell with offset ${pos} found`);
|
|
112
|
+
}
|
|
113
|
+
// Find the next cell in the given direction, starting from the cell
|
|
114
|
+
// at `pos`, if any.
|
|
115
|
+
nextCell(pos, axis, dir) {
|
|
116
|
+
const { left, right, top, bottom } = this.findCell(pos);
|
|
117
|
+
if (axis == 'horiz') {
|
|
118
|
+
if (dir < 0 ? left == 0 : right == this.width)
|
|
119
|
+
return null;
|
|
120
|
+
return this.map[top * this.width + (dir < 0 ? left - 1 : right)];
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
if (dir < 0 ? top == 0 : bottom == this.height)
|
|
124
|
+
return null;
|
|
125
|
+
return this.map[left + this.width * (dir < 0 ? top - 1 : bottom)];
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
// Get the rectangle spanning the two given cells.
|
|
129
|
+
rectBetween(a, b) {
|
|
130
|
+
const { left: leftA, right: rightA, top: topA, bottom: bottomA, } = this.findCell(a);
|
|
131
|
+
const { left: leftB, right: rightB, top: topB, bottom: bottomB, } = this.findCell(b);
|
|
132
|
+
return {
|
|
133
|
+
left: Math.min(leftA, leftB),
|
|
134
|
+
top: Math.min(topA, topB),
|
|
135
|
+
right: Math.max(rightA, rightB),
|
|
136
|
+
bottom: Math.max(bottomA, bottomB),
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
// Return the position of all cells that have the top left corner in
|
|
140
|
+
// the given rectangle.
|
|
141
|
+
cellsInRect(rect) {
|
|
142
|
+
const result = [];
|
|
143
|
+
const seen = {};
|
|
144
|
+
for (let row = rect.top; row < rect.bottom; row++) {
|
|
145
|
+
for (let col = rect.left; col < rect.right; col++) {
|
|
146
|
+
const index = row * this.width + col;
|
|
147
|
+
const pos = this.map[index];
|
|
148
|
+
if (seen[pos])
|
|
149
|
+
continue;
|
|
150
|
+
seen[pos] = true;
|
|
151
|
+
if ((col == rect.left && col && this.map[index - 1] == pos) ||
|
|
152
|
+
(row == rect.top && row && this.map[index - this.width] == pos)) {
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
155
|
+
result.push(pos);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return result;
|
|
159
|
+
}
|
|
160
|
+
// Return the position at which the cell at the given row and column
|
|
161
|
+
// starts, or would start, if a cell started there.
|
|
162
|
+
positionAt(row, col, table) {
|
|
163
|
+
for (let i = 0, rowStart = 0;; i++) {
|
|
164
|
+
const rowEnd = rowStart + table.child(i).nodeSize;
|
|
165
|
+
if (i == row) {
|
|
166
|
+
let index = col + row * this.width;
|
|
167
|
+
const rowEndIndex = (row + 1) * this.width;
|
|
168
|
+
// Skip past cells from previous rows (via rowspan)
|
|
169
|
+
while (index < rowEndIndex && this.map[index] < rowStart)
|
|
170
|
+
index++;
|
|
171
|
+
return index == rowEndIndex ? rowEnd - 1 : this.map[index];
|
|
172
|
+
}
|
|
173
|
+
rowStart = rowEnd;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
// Find the table map for the given table node.
|
|
177
|
+
static get(table) {
|
|
178
|
+
return readFromCache(table) || addToCache(table, computeMap(table));
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
// Compute a table map.
|
|
182
|
+
function computeMap(table) {
|
|
183
|
+
if (table.type.spec.tableRole != 'table') {
|
|
184
|
+
throw new RangeError('Not a table node: ' + table.type.name);
|
|
185
|
+
}
|
|
186
|
+
const width = findWidth(table), height = table.childCount;
|
|
187
|
+
const map = [];
|
|
188
|
+
let mapPos = 0;
|
|
189
|
+
let problems = null;
|
|
190
|
+
const colWidths = [];
|
|
191
|
+
for (let i = 0, e = width * height; i < e; i++)
|
|
192
|
+
map[i] = 0;
|
|
193
|
+
for (let row = 0, pos = 0; row < height; row++) {
|
|
194
|
+
const rowNode = table.child(row);
|
|
195
|
+
pos++;
|
|
196
|
+
for (let i = 0;; i++) {
|
|
197
|
+
while (mapPos < map.length && map[mapPos] != 0)
|
|
198
|
+
mapPos++;
|
|
199
|
+
if (i == rowNode.childCount)
|
|
200
|
+
break;
|
|
201
|
+
const cellNode = rowNode.child(i);
|
|
202
|
+
const { colspan, rowspan, colwidth } = cellNode.attrs;
|
|
203
|
+
for (let h = 0; h < rowspan; h++) {
|
|
204
|
+
if (h + row >= height) {
|
|
205
|
+
(problems || (problems = [])).push({
|
|
206
|
+
type: 'overlong_rowspan',
|
|
207
|
+
pos,
|
|
208
|
+
n: rowspan - h,
|
|
209
|
+
});
|
|
210
|
+
break;
|
|
211
|
+
}
|
|
212
|
+
const start = mapPos + h * width;
|
|
213
|
+
for (let w = 0; w < colspan; w++) {
|
|
214
|
+
if (map[start + w] == 0)
|
|
215
|
+
map[start + w] = pos;
|
|
216
|
+
else {
|
|
217
|
+
(problems || (problems = [])).push({
|
|
218
|
+
type: 'collision',
|
|
219
|
+
row,
|
|
220
|
+
pos,
|
|
221
|
+
n: colspan - w,
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
const colW = colwidth && colwidth[w];
|
|
225
|
+
if (colW) {
|
|
226
|
+
const widthIndex = ((start + w) % width) * 2, prev = colWidths[widthIndex];
|
|
227
|
+
if (prev == null ||
|
|
228
|
+
(prev != colW && colWidths[widthIndex + 1] == 1)) {
|
|
229
|
+
colWidths[widthIndex] = colW;
|
|
230
|
+
colWidths[widthIndex + 1] = 1;
|
|
231
|
+
}
|
|
232
|
+
else if (prev == colW) {
|
|
233
|
+
colWidths[widthIndex + 1]++;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
mapPos += colspan;
|
|
239
|
+
pos += cellNode.nodeSize;
|
|
240
|
+
}
|
|
241
|
+
const expectedPos = (row + 1) * width;
|
|
242
|
+
let missing = 0;
|
|
243
|
+
while (mapPos < expectedPos)
|
|
244
|
+
if (map[mapPos++] == 0)
|
|
245
|
+
missing++;
|
|
246
|
+
if (missing) {
|
|
247
|
+
(problems || (problems = [])).push({ type: 'missing', row, n: missing });
|
|
248
|
+
}
|
|
249
|
+
pos++;
|
|
250
|
+
}
|
|
251
|
+
if (width === 0 || height === 0) {
|
|
252
|
+
(problems || (problems = [])).push({ type: 'zero_sized' });
|
|
253
|
+
}
|
|
254
|
+
const tableMap = new TableMap(width, height, map, problems);
|
|
255
|
+
let badWidths = false;
|
|
256
|
+
// For columns that have defined widths, but whose widths disagree
|
|
257
|
+
// between rows, fix up the cells whose width doesn't match the
|
|
258
|
+
// computed one.
|
|
259
|
+
for (let i = 0; !badWidths && i < colWidths.length; i += 2) {
|
|
260
|
+
if (colWidths[i] != null && colWidths[i + 1] < height)
|
|
261
|
+
badWidths = true;
|
|
262
|
+
}
|
|
263
|
+
if (badWidths)
|
|
264
|
+
findBadColWidths(tableMap, colWidths, table);
|
|
265
|
+
return tableMap;
|
|
266
|
+
}
|
|
267
|
+
function findWidth(table) {
|
|
268
|
+
let width = -1;
|
|
269
|
+
let hasRowSpan = false;
|
|
270
|
+
for (let row = 0; row < table.childCount; row++) {
|
|
271
|
+
const rowNode = table.child(row);
|
|
272
|
+
let rowWidth = 0;
|
|
273
|
+
if (hasRowSpan) {
|
|
274
|
+
for (let j = 0; j < row; j++) {
|
|
275
|
+
const prevRow = table.child(j);
|
|
276
|
+
for (let i = 0; i < prevRow.childCount; i++) {
|
|
277
|
+
const cell = prevRow.child(i);
|
|
278
|
+
if (j + cell.attrs.rowspan > row)
|
|
279
|
+
rowWidth += cell.attrs.colspan;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
for (let i = 0; i < rowNode.childCount; i++) {
|
|
284
|
+
const cell = rowNode.child(i);
|
|
285
|
+
rowWidth += cell.attrs.colspan;
|
|
286
|
+
if (cell.attrs.rowspan > 1)
|
|
287
|
+
hasRowSpan = true;
|
|
288
|
+
}
|
|
289
|
+
if (width == -1)
|
|
290
|
+
width = rowWidth;
|
|
291
|
+
else if (width != rowWidth)
|
|
292
|
+
width = Math.max(width, rowWidth);
|
|
293
|
+
}
|
|
294
|
+
return width;
|
|
295
|
+
}
|
|
296
|
+
function findBadColWidths(map, colWidths, table) {
|
|
297
|
+
if (!map.problems)
|
|
298
|
+
map.problems = [];
|
|
299
|
+
const seen = {};
|
|
300
|
+
for (let i = 0; i < map.map.length; i++) {
|
|
301
|
+
const pos = map.map[i];
|
|
302
|
+
if (seen[pos])
|
|
303
|
+
continue;
|
|
304
|
+
seen[pos] = true;
|
|
305
|
+
const node = table.nodeAt(pos);
|
|
306
|
+
if (!node) {
|
|
307
|
+
throw new RangeError(`No cell with offset ${pos} found`);
|
|
308
|
+
}
|
|
309
|
+
let updated = null;
|
|
310
|
+
const attrs = node.attrs;
|
|
311
|
+
for (let j = 0; j < attrs.colspan; j++) {
|
|
312
|
+
const col = (i + j) % map.width;
|
|
313
|
+
const colWidth = colWidths[col * 2];
|
|
314
|
+
if (colWidth != null &&
|
|
315
|
+
(!attrs.colwidth || attrs.colwidth[j] != colWidth)) {
|
|
316
|
+
(updated || (updated = freshColWidth(attrs)))[j] = colWidth;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
if (updated) {
|
|
320
|
+
map.problems.unshift({
|
|
321
|
+
type: 'colwidth mismatch',
|
|
322
|
+
pos,
|
|
323
|
+
colwidth: updated,
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
function freshColWidth(attrs) {
|
|
329
|
+
if (attrs.colwidth)
|
|
330
|
+
return attrs.colwidth.slice();
|
|
331
|
+
const result = [];
|
|
332
|
+
for (let i = 0; i < attrs.colspan; i++)
|
|
333
|
+
result.push(0);
|
|
334
|
+
return result;
|
|
335
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Node } from 'prosemirror-model';
|
|
2
|
+
import { NodeView, ViewMutationRecord } from 'prosemirror-view';
|
|
3
|
+
/**
|
|
4
|
+
* @public
|
|
5
|
+
*/
|
|
6
|
+
export declare class TableView implements NodeView {
|
|
7
|
+
node: Node;
|
|
8
|
+
defaultCellMinWidth: number;
|
|
9
|
+
dom: HTMLDivElement;
|
|
10
|
+
table: HTMLTableElement;
|
|
11
|
+
colgroup: HTMLTableColElement;
|
|
12
|
+
contentDOM: HTMLTableSectionElement;
|
|
13
|
+
constructor(node: Node, defaultCellMinWidth: number);
|
|
14
|
+
update(node: Node): boolean;
|
|
15
|
+
ignoreMutation(record: ViewMutationRecord): boolean;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* @public
|
|
19
|
+
*/
|
|
20
|
+
export declare function updateColumnsOnResize(node: Node, colgroup: HTMLTableColElement, table: HTMLTableElement, defaultCellMinWidth: number, overrideCol?: number, overrideValue?: number): void;
|
|
21
|
+
//# sourceMappingURL=TableView.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TableView.d.ts","sourceRoot":"","sources":["../../src/utilities/TableView.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAGhE;;GAEG;AACH,qBAAa,SAAU,YAAW,QAAQ;IAO/B,IAAI,EAAE,IAAI;IACV,mBAAmB,EAAE,MAAM;IAP7B,GAAG,EAAE,cAAc,CAAC;IACpB,KAAK,EAAE,gBAAgB,CAAC;IACxB,QAAQ,EAAE,mBAAmB,CAAC;IAC9B,UAAU,EAAE,uBAAuB,CAAC;gBAGlC,IAAI,EAAE,IAAI,EACV,mBAAmB,EAAE,MAAM;IAcpC,MAAM,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO;IAY3B,cAAc,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO;CAMpD;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,IAAI,EACV,QAAQ,EAAE,mBAAmB,EAC7B,KAAK,EAAE,gBAAgB,EACvB,mBAAmB,EAAE,MAAM,EAC3B,WAAW,CAAC,EAAE,MAAM,EACpB,aAAa,CAAC,EAAE,MAAM,GACrB,IAAI,CA0CN"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @public
|
|
3
|
+
*/
|
|
4
|
+
export class TableView {
|
|
5
|
+
constructor(node, defaultCellMinWidth) {
|
|
6
|
+
Object.defineProperty(this, "node", {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
configurable: true,
|
|
9
|
+
writable: true,
|
|
10
|
+
value: node
|
|
11
|
+
});
|
|
12
|
+
Object.defineProperty(this, "defaultCellMinWidth", {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
configurable: true,
|
|
15
|
+
writable: true,
|
|
16
|
+
value: defaultCellMinWidth
|
|
17
|
+
});
|
|
18
|
+
Object.defineProperty(this, "dom", {
|
|
19
|
+
enumerable: true,
|
|
20
|
+
configurable: true,
|
|
21
|
+
writable: true,
|
|
22
|
+
value: void 0
|
|
23
|
+
});
|
|
24
|
+
Object.defineProperty(this, "table", {
|
|
25
|
+
enumerable: true,
|
|
26
|
+
configurable: true,
|
|
27
|
+
writable: true,
|
|
28
|
+
value: void 0
|
|
29
|
+
});
|
|
30
|
+
Object.defineProperty(this, "colgroup", {
|
|
31
|
+
enumerable: true,
|
|
32
|
+
configurable: true,
|
|
33
|
+
writable: true,
|
|
34
|
+
value: void 0
|
|
35
|
+
});
|
|
36
|
+
Object.defineProperty(this, "contentDOM", {
|
|
37
|
+
enumerable: true,
|
|
38
|
+
configurable: true,
|
|
39
|
+
writable: true,
|
|
40
|
+
value: void 0
|
|
41
|
+
});
|
|
42
|
+
this.dom = document.createElement('div');
|
|
43
|
+
this.dom.className = 'tableWrapper';
|
|
44
|
+
this.table = this.dom.appendChild(document.createElement('table'));
|
|
45
|
+
this.table.style.setProperty('--default-cell-min-width', `${defaultCellMinWidth}px`);
|
|
46
|
+
this.colgroup = this.table.appendChild(document.createElement('colgroup'));
|
|
47
|
+
updateColumnsOnResize(node, this.colgroup, this.table, defaultCellMinWidth);
|
|
48
|
+
this.contentDOM = this.table.appendChild(document.createElement('tbody'));
|
|
49
|
+
}
|
|
50
|
+
update(node) {
|
|
51
|
+
if (node.type != this.node.type)
|
|
52
|
+
return false;
|
|
53
|
+
this.node = node;
|
|
54
|
+
updateColumnsOnResize(node, this.colgroup, this.table, this.defaultCellMinWidth);
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
ignoreMutation(record) {
|
|
58
|
+
return (record.type == 'attributes' &&
|
|
59
|
+
(record.target == this.table || this.colgroup.contains(record.target)));
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* @public
|
|
64
|
+
*/
|
|
65
|
+
export function updateColumnsOnResize(node, colgroup, table, defaultCellMinWidth, overrideCol, overrideValue) {
|
|
66
|
+
let totalWidth = 0;
|
|
67
|
+
let fixedWidth = true;
|
|
68
|
+
let nextDOM = colgroup.firstChild;
|
|
69
|
+
const row = node.firstChild;
|
|
70
|
+
if (!row)
|
|
71
|
+
return;
|
|
72
|
+
for (let i = 0, col = 0; i < row.childCount; i++) {
|
|
73
|
+
const { colspan, colwidth } = row.child(i).attrs;
|
|
74
|
+
for (let j = 0; j < colspan; j++, col++) {
|
|
75
|
+
const hasWidth = overrideCol == col
|
|
76
|
+
? overrideValue
|
|
77
|
+
: colwidth && colwidth[j];
|
|
78
|
+
const cssWidth = hasWidth ? hasWidth + 'px' : '';
|
|
79
|
+
totalWidth += hasWidth || defaultCellMinWidth;
|
|
80
|
+
if (!hasWidth)
|
|
81
|
+
fixedWidth = false;
|
|
82
|
+
if (!nextDOM) {
|
|
83
|
+
const col = document.createElement('col');
|
|
84
|
+
col.style.width = cssWidth;
|
|
85
|
+
colgroup.appendChild(col);
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
if (nextDOM.style.width != cssWidth) {
|
|
89
|
+
nextDOM.style.width = cssWidth;
|
|
90
|
+
}
|
|
91
|
+
nextDOM = nextDOM.nextSibling;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
while (nextDOM) {
|
|
96
|
+
const after = nextDOM.nextSibling;
|
|
97
|
+
nextDOM.parentNode?.removeChild(nextDOM);
|
|
98
|
+
nextDOM = after;
|
|
99
|
+
}
|
|
100
|
+
if (fixedWidth) {
|
|
101
|
+
table.style.width = totalWidth + 'px';
|
|
102
|
+
table.style.minWidth = '';
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
table.style.width = '';
|
|
106
|
+
table.style.minWidth = totalWidth + 'px';
|
|
107
|
+
}
|
|
108
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { Node as ProsemirrorNode } from 'prosemirror-model';
|
|
2
|
+
import { EditorState, Plugin, Transaction } from 'prosemirror-state';
|
|
3
|
+
import { DecorationSet, EditorView, NodeView } from 'prosemirror-view';
|
|
4
|
+
/**
|
|
5
|
+
* @public
|
|
6
|
+
*/
|
|
7
|
+
export declare const columnResizingPluginKey: any;
|
|
8
|
+
/**
|
|
9
|
+
* @public
|
|
10
|
+
*/
|
|
11
|
+
export type ColumnResizingOptions = {
|
|
12
|
+
handleWidth?: number;
|
|
13
|
+
/**
|
|
14
|
+
* Minimum width of a cell /column. The column cannot be resized smaller than this.
|
|
15
|
+
*/
|
|
16
|
+
cellMinWidth?: number;
|
|
17
|
+
/**
|
|
18
|
+
* The default minWidth of a cell / column when it doesn't have an explicit width (i.e.: it has not been resized manually)
|
|
19
|
+
*/
|
|
20
|
+
defaultCellMinWidth?: number;
|
|
21
|
+
lastColumnResizable?: boolean;
|
|
22
|
+
/**
|
|
23
|
+
* A custom node view for the rendering table nodes. By default, the plugin
|
|
24
|
+
* uses the {@link TableView} class. You can explicitly set this to `null` to
|
|
25
|
+
* not use a custom node view.
|
|
26
|
+
*/
|
|
27
|
+
View?: (new (node: ProsemirrorNode, cellMinWidth: number, view: EditorView) => NodeView) | null;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* @public
|
|
31
|
+
*/
|
|
32
|
+
export type Dragging = {
|
|
33
|
+
startX: number;
|
|
34
|
+
startWidth: number;
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* @public
|
|
38
|
+
*/
|
|
39
|
+
export declare function columnResizing({ handleWidth, cellMinWidth, defaultCellMinWidth, View, lastColumnResizable, }?: ColumnResizingOptions): Plugin;
|
|
40
|
+
/**
|
|
41
|
+
* @public
|
|
42
|
+
*/
|
|
43
|
+
export declare class ResizeState {
|
|
44
|
+
activeHandle: number;
|
|
45
|
+
dragging: Dragging | false;
|
|
46
|
+
constructor(activeHandle: number, dragging: Dragging | false);
|
|
47
|
+
apply(tr: Transaction): ResizeState;
|
|
48
|
+
}
|
|
49
|
+
export declare function handleDecorations(state: EditorState, cell: number): DecorationSet;
|
|
50
|
+
//# sourceMappingURL=columnResizing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"columnResizing.d.ts","sourceRoot":"","sources":["../../src/utilities/columnResizing.ts"],"names":[],"mappings":"AACA,OAAO,EAAS,IAAI,IAAI,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACnE,OAAO,EAAE,WAAW,EAAE,MAAM,EAAa,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChF,OAAO,EAEL,aAAa,EACb,UAAU,EACV,QAAQ,EACT,MAAM,kBAAkB,CAAC;AAM1B;;GAEG;AACH,eAAO,MAAM,uBAAuB,KAEnC,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAAG;IAClC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;OAEG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B;;;;OAIG;IACH,IAAI,CAAC,EACD,CAAC,KACD,IAAI,EAAE,eAAe,EACrB,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE,UAAU,KACb,QAAQ,CAAC,GACZ,IAAI,CAAC;CACV,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,QAAQ,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC;AAE9D;;GAEG;AACH,wBAAgB,cAAc,CAAC,EAC7B,WAAe,EACf,YAAiB,EACjB,mBAAyB,EACzB,IAAgB,EAChB,mBAA0B,GAC3B,GAAE,qBAA0B,GAAG,MAAM,CAiDrC;AAED;;GAEG;AACH,qBAAa,WAAW;IAEb,YAAY,EAAE,MAAM;IACpB,QAAQ,EAAE,QAAQ,GAAG,KAAK;gBAD1B,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,QAAQ,GAAG,KAAK;IAGnC,KAAK,CAAC,EAAE,EAAE,WAAW,GAAG,WAAW;CAkBpC;AA4PD,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,WAAW,EAClB,IAAI,EAAE,MAAM,GACX,aAAa,CAwCf"}
|