UNPKG

15.2 kBTypeScriptView Raw
1import { Plugin } from '@ckeditor/ckeditor5-core';
2import { Element as ModelElement, Range as ModelRange } from '@ckeditor/ckeditor5-engine';
3import Writer from '@ckeditor/ckeditor5-engine/src/model/writer';
4import TableWalker from './tablewalker';
5import ModelSelection from '@ckeditor/ckeditor5-engine/src/model/selection';
6
7/**
8 * The table utilities plugin.
9 */
10export default class TableUtils extends Plugin {
11 static readonly pluginName: 'TableUtils';
12 init(): void;
13
14 /**
15 * Returns the table cell location as an object with table row and table column indexes.
16 *
17 * For instance, in the table below:
18 *
19 * 0 1 2 3
20 * +---+---+---+---+
21 * 0 | a | b | c |
22 * + + +---+
23 * 1 | | | d |
24 * +---+---+ +---+
25 * 2 | e | | f |
26 * +---+---+---+---+
27 *
28 * the method will return:
29 *
30 * const cellA = table.getNodeByPath( [ 0, 0 ] );
31 * editor.plugins.get( 'TableUtils' ).getCellLocation( cellA );
32 * // will return { row: 0, column: 0 }
33 *
34 * const cellD = table.getNodeByPath( [ 1, 0 ] );
35 * editor.plugins.get( 'TableUtils' ).getCellLocation( cellD );
36 * // will return { row: 1, column: 3 }
37 */
38 getCellLocation(tableCell: ModelElement): { row: number; column: number } | void;
39
40 /**
41 * Creates an empty table with a proper structure. The table needs to be inserted into the model,
42 * for example, by using the {@link module:engine/model/model~Model#insertContent} function.
43 *
44 * model.change( ( writer ) => {
45 * // Create a table of 2 rows and 7 columns:
46 * const table = tableUtils.createTable( writer, { rows: 2, columns: 7 } );
47 *
48 * // Insert a table to the model at the best position taking the current selection:
49 * model.insertContent( table );
50 * }
51 */
52 createTable(
53 writer: Writer,
54 options?: { rows?: number; columns?: number; headingRows?: number; headingColumns?: number },
55 ): ModelElement;
56
57 /**
58 * Inserts rows into a table.
59 *
60 * editor.plugins.get( 'TableUtils' ).insertRows( table, { at: 1, rows: 2 } );
61 *
62 * Assuming the table on the left, the above code will transform it to the table on the right:
63 *
64 * row index
65 * 0 +---+---+---+ `at` = 1, +---+---+---+ 0
66 * | a | b | c | `rows` = 2, | a | b | c |
67 * 1 + +---+---+ <-- insert here + +---+---+ 1
68 * | | d | e | | | | |
69 * 2 + +---+---+ will give: + +---+---+ 2
70 * | | f | g | | | | |
71 * 3 +---+---+---+ + +---+---+ 3
72 * | | d | e |
73 * + +---+---+ 4
74 * + + f | g |
75 * +---+---+---+ 5
76 */
77 insertRows(table: ModelElement, options?: { at?: number; rows?: number; copyStructureFromAbove?: boolean }): void;
78
79 /**
80 * Inserts columns into a table.
81 *
82 * editor.plugins.get( 'TableUtils' ).insertColumns( table, { at: 1, columns: 2 } );
83 *
84 * Assuming the table on the left, the above code will transform it to the table on the right:
85 *
86 * 0 1 2 3 0 1 2 3 4 5
87 * +---+---+---+ +---+---+---+---+---+
88 * | a | b | | a | b |
89 * + +---+ + +---+
90 * | | c | | | c |
91 * +---+---+---+ will give: +---+---+---+---+---+
92 * | d | e | f | | d | | | e | f |
93 * +---+ +---+ +---+---+---+ +---+
94 * | g | | h | | g | | | | h |
95 * +---+---+---+ +---+---+---+---+---+
96 * | i | | i |
97 * +---+---+---+ +---+---+---+---+---+
98 * ^---- insert here, `at` = 1, `columns` = 2
99 */
100 insertColumns(table: ModelElement, options?: { at?: number; columns?: number }): void;
101
102 /**
103 * Removes rows from the given `table`.
104 *
105 * This method re-calculates the table geometry including `rowspan` attribute of table cells overlapping removed rows
106 * and table headings values.
107 *
108 * editor.plugins.get( 'TableUtils' ).removeRows( table, { at: 1, rows: 2 } );
109 *
110 * Executing the above code in the context of the table on the left will transform its structure as presented on the right:
111 *
112 * row index
113 * ┌───┬───┬───┐ `at` = 1 ┌───┬───┬───┐
114 * 0 │ a │ b │ c │ `rows` = 2 │ a │ b │ c │ 0
115 * │ ├───┼───┤ │ ├───┼───┤
116 * 1 │ │ d │ e │ <-- remove from here │ │ d │ g │ 1
117 * │ │ ├───┤ will give: ├───┼───┼───┤
118 * 2 │ │ │ f │ │ h │ i │ j │ 2
119 * │ │ ├───┤ └───┴───┴───┘
120 * 3 │ │ │ g │
121 * ├───┼───┼───┤
122 * 4 │ h │ i │ j │
123 * └───┴───┴───┘
124 */
125 removeRows(table: ModelElement, options?: { at?: number; rows?: number }): void;
126
127 /**
128 * Removes columns from the given `table`.
129 *
130 * This method re-calculates the table geometry including the `colspan` attribute of table cells overlapping removed columns
131 * and table headings values.
132 *
133 * editor.plugins.get( 'TableUtils' ).removeColumns( table, { at: 1, columns: 2 } );
134 *
135 * Executing the above code in the context of the table on the left will transform its structure as presented on the right:
136 *
137 * 0 1 2 3 4 0 1 2
138 * ┌───────────────┬───┐ ┌───────┬───┐
139 * │ a │ b │ │ a │ b │
140 * │ ├───┤ │ ├───┤
141 * │ │ c │ │ │ c │
142 * ├───┬───┬───┬───┼───┤ will give: ├───┬───┼───┤
143 * │ d │ e │ f │ g │ h │ │ d │ g │ h │
144 * ├───┼───┼───┤ ├───┤ ├───┤ ├───┤
145 * │ i │ j │ k │ │ l │ │ i │ │ l │
146 * ├───┴───┴───┴───┴───┤ ├───┴───┴───┤
147 * │ m │ │ m │
148 * └───────────────────┘ └───────────┘
149 * ^---- remove from here, `at` = 1, `columns` = 2
150 */
151 removeColumns(table: ModelElement, options?: { at?: number; columns?: number }): void;
152
153 /**
154 * Divides a table cell vertically into several ones.
155 *
156 * The cell will be visually split into more cells by updating colspans of other cells in a column
157 * and inserting cells (columns) after that cell.
158 *
159 * In the table below, if cell "a" is split into 3 cells:
160 *
161 * +---+---+---+
162 * | a | b | c |
163 * +---+---+---+
164 * | d | e | f |
165 * +---+---+---+
166 *
167 * it will result in the table below:
168 *
169 * +---+---+---+---+---+
170 * | a | | | b | c |
171 * +---+---+---+---+---+
172 * | d | e | f |
173 * +---+---+---+---+---+
174 *
175 * So cell "d" will get its `colspan` updated to `3` and 2 cells will be added (2 columns will be created).
176 *
177 * Splitting a cell that already has a `colspan` attribute set will distribute the cell `colspan` evenly and the remainder
178 * will be left to the original cell:
179 *
180 * +---+---+---+
181 * | a |
182 * +---+---+---+
183 * | b | c | d |
184 * +---+---+---+
185 *
186 * Splitting cell "a" with `colspan=3` into 2 cells will create 1 cell with a `colspan=a` and cell "a" that will have `colspan=2`:
187 *
188 * +---+---+---+
189 * | a | |
190 * +---+---+---+
191 * | b | c | d |
192 * +---+---+---+
193 */
194 splitCellVertically(tableCell: ModelElement, numberOfCells: number): void;
195
196 /**
197 * Divides a table cell horizontally into several ones.
198 *
199 * The cell will be visually split into more cells by updating rowspans of other cells in the row and inserting rows with a single cell
200 * below.
201 *
202 * If in the table below cell "b" is split into 3 cells:
203 *
204 * +---+---+---+
205 * | a | b | c |
206 * +---+---+---+
207 * | d | e | f |
208 * +---+---+---+
209 *
210 * It will result in the table below:
211 *
212 * +---+---+---+
213 * | a | b | c |
214 * + +---+ +
215 * | | | |
216 * + +---+ +
217 * | | | |
218 * +---+---+---+
219 * | d | e | f |
220 * +---+---+---+
221 *
222 * So cells "a" and "b" will get their `rowspan` updated to `3` and 2 rows with a single cell will be added.
223 *
224 * Splitting a cell that already has a `rowspan` attribute set will distribute the cell `rowspan` evenly and the remainder
225 * will be left to the original cell:
226 *
227 * +---+---+---+
228 * | a | b | c |
229 * + +---+---+
230 * | | d | e |
231 * + +---+---+
232 * | | f | g |
233 * + +---+---+
234 * | | h | i |
235 * +---+---+---+
236 *
237 * Splitting cell "a" with `rowspan=4` into 3 cells will create 2 cells with a `rowspan=1` and cell "a" will have `rowspan=2`:
238 *
239 * +---+---+---+
240 * | a | b | c |
241 * + +---+---+
242 * | | d | e |
243 * +---+---+---+
244 * | | f | g |
245 * +---+---+---+
246 * | | h | i |
247 * +---+---+---+
248 */
249 splitCellHorizontally(tableCell: ModelElement, numberOfCells?: number): void;
250
251 /**
252 * Returns the number of columns for a given table.
253 *
254 * editor.plugins.get( 'TableUtils' ).getColumns( table );
255 */
256 getColumns(table: ModelElement): number;
257
258 /**
259 * Returns the number of rows for a given table. Any other element present in the table model is omitted.
260 *
261 * editor.plugins.get( 'TableUtils' ).getRows( table );
262 */
263 getRows(table: ModelElement): number;
264
265 /**
266 * Creates an instance of the table walker.
267 *
268 * The table walker iterates internally by traversing the table from row index = 0 and column index = 0.
269 * It walks row by row and column by column in order to output values defined in the options.
270 * By default it will output only the locations that are occupied by a cell. To include also spanned rows and columns,
271 * pass the `includeAllSlots` option.
272 */
273 createTableWalker(
274 table: ModelElement,
275 options?: {
276 row?: number;
277 startRow?: number;
278 endRow?: number;
279 column?: number;
280 startColumn?: number;
281 endColumn?: number;
282 includeAllSlots?: boolean;
283 },
284 ): TableWalker;
285
286 /**
287 * Returns all model table cells that are fully selected (from the outside)
288 * within the provided model selection's ranges.
289 *
290 * To obtain the cells selected from the inside, use
291 * {@link #getTableCellsContainingSelection}.
292 */
293 getSelectedTableCells(selection: ModelSelection): ModelElement[];
294
295 /**
296 * Returns all model table cells that the provided model selection's ranges
297 * {@link module:engine/model/range~Range#start} inside.
298 *
299 * To obtain the cells selected from the outside, use
300 * {@link #getSelectedTableCells}.
301 */
302 getTableCellsContainingSelection(selection: ModelSelection): ModelElement[];
303
304 /**
305 * Returns all model table cells that are either completely selected
306 * by selection ranges or host selection range
307 * {@link module:engine/model/range~Range#start start positions} inside them.
308 *
309 * Combines {@link #getTableCellsContainingSelection} and
310 * {@link #getSelectedTableCells}.
311 */
312 getSelectionAffectedTableCells(selection: ModelSelection): ModelElement[];
313
314 /**
315 * Returns an object with the `first` and `last` row index contained in the given `tableCells`.
316 *
317 * const selectedTableCells = getSelectedTableCells( editor.model.document.selection );
318 *
319 * const { first, last } = getRowIndexes( selectedTableCells );
320 *
321 * console.log( `Selected rows: ${ first } to ${ last }` );
322 */
323 getRowIndexes(tableCells: ModelElement[]): { first: number; last: number };
324
325 /**
326 * Returns an object with the `first` and `last` column index contained in the given `tableCells`.
327 *
328 * const selectedTableCells = getSelectedTableCells( editor.model.document.selection );
329 *
330 * const { first, last } = getColumnIndexes( selectedTableCells );
331 *
332 * console.log( `Selected columns: ${ first } to ${ last }` );
333 */
334 getColumnIndexes(tableCells: ModelElement[]): { first: number; last: number };
335
336 /**
337 * Checks if the selection contains cells that do not exceed rectangular selection.
338 *
339 * In a table below:
340 *
341 * ┌───┬───┬───┬───┐
342 * │ a │ b │ c │ d │
343 * ├───┴───┼───┤ │
344 * │ e │ f │ │
345 * │ ├───┼───┤
346 * │ │ g │ h │
347 * └───────┴───┴───┘
348 *
349 * Valid selections are these which create a solid rectangle (without gaps), such as:
350 * - a, b (two horizontal cells)
351 * - c, f (two vertical cells)
352 * - a, b, e (cell "e" spans over four cells)
353 * - c, d, f (cell d spans over a cell in the row below)
354 *
355 * While an invalid selection would be:
356 * - a, c (the unselected cell "b" creates a gap)
357 * - f, g, h (cell "d" spans over a cell from the row of "f" cell - thus creates a gap)
358 */
359 isSelectionRectangular(selectedTableCells: ModelElement[]): boolean;
360
361 /**
362 * Returns array of sorted ranges.
363 */
364 sortRanges(ranges: Iterable<ModelRange>): ModelRange[];
365}
366
367declare module '@ckeditor/ckeditor5-core/src/plugincollection' {
368 interface Plugins {
369 TableUtils: TableUtils;
370 }
371}