UNPKG

11 kBTypeScriptView Raw
1/**
2 * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
3 * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4 */
5/**
6 * @module table/tablewalker
7 */
8import type { Element, Position } from 'ckeditor5/src/engine';
9/**
10 * An object with configuration for `TableWalker`.
11 */
12export interface TableWalkerOptions {
13 /**
14 * A row index for which this iterator will output cells. Can't be used together with `startRow` and `endRow`.
15 */
16 row?: number | null;
17 /**
18 * A row index from which this iterator should start. Can't be used together with `row`. Default value is 0.
19 */
20 startRow?: number;
21 /**
22 * A row index at which this iterator should end. Can't be used together with `row`.
23 */
24 endRow?: number;
25 /**
26 * A column index for which this iterator will output cells. Can't be used together with `startColumn` and `endColumn`.
27 */
28 column?: number;
29 /**
30 * A column index from which this iterator should start. Can't be used together with `column`. Default value is 0.
31 */
32 startColumn?: number;
33 /**
34 * A column index at which this iterator should end. Can't be used together with `column`.
35 */
36 endColumn?: number;
37 /**
38 * Also return values for spanned cells. Default value is false.
39 */
40 includeAllSlots?: boolean;
41}
42/**
43 * The table iterator class. It allows to iterate over table cells. For each cell the iterator yields
44 * {@link module:table/tablewalker~TableSlot} with proper table cell attributes.
45 */
46export default class TableWalker implements IterableIterator<TableSlot> {
47 /**
48 * The walker's table element.
49 *
50 * @internal
51 */
52 readonly _table: Element;
53 /**
54 * A row index from which this iterator will start.
55 */
56 private readonly _startRow;
57 /**
58 * A row index at which this iterator will end.
59 */
60 private readonly _endRow?;
61 /**
62 * If set, the table walker will only output cells from a given column and following ones or cells that overlap them.
63 */
64 private readonly _startColumn;
65 /**
66 * If set, the table walker will only output cells up to a given column.
67 */
68 private readonly _endColumn?;
69 /**
70 * Enables output of spanned cells that are normally not yielded.
71 */
72 private readonly _includeAllSlots;
73 /**
74 * Row indexes to skip from the iteration.
75 */
76 private readonly _skipRows;
77 /**
78 * The current row index.
79 *
80 * @internal
81 */
82 _row: number;
83 /**
84 * The index of the current row element in the table.
85 *
86 * @internal
87 */
88 _rowIndex: number;
89 /**
90 * The current column index.
91 *
92 * @internal
93 */
94 _column: number;
95 /**
96 * The cell index in a parent row. For spanned cells when {@link #_includeAllSlots} is set to `true`,
97 * this represents the index of the next table cell.
98 *
99 * @internal
100 */
101 _cellIndex: number;
102 /**
103 * Holds a map of spanned cells in a table.
104 */
105 private readonly _spannedCells;
106 /**
107 * Index of the next column where a cell is anchored.
108 */
109 private _nextCellAtColumn;
110 /**
111 * Creates an instance of the table walker.
112 *
113 * The table walker iterates internally by traversing the table from row index = 0 and column index = 0.
114 * It walks row by row and column by column in order to output values defined in the constructor.
115 * By default it will output only the locations that are occupied by a cell. To include also spanned rows and columns,
116 * pass the `includeAllSlots` option to the constructor.
117 *
118 * The most important values of the iterator are column and row indexes of a cell.
119 *
120 * See {@link module:table/tablewalker~TableSlot} what values are returned by the table walker.
121 *
122 * To iterate over a given row:
123 *
124 * ```ts
125 * const tableWalker = new TableWalker( table, { startRow: 1, endRow: 2 } );
126 *
127 * for ( const tableSlot of tableWalker ) {
128 * console.log( 'A cell at row', tableSlot.row, 'and column', tableSlot.column );
129 * }
130 * ```
131 *
132 * For instance the code above for the following table:
133 *
134 * +----+----+----+----+----+----+
135 * | 00 | 02 | 03 | 04 | 05 |
136 * | +----+----+----+----+
137 * | | 12 | 14 | 15 |
138 * | +----+----+----+ +
139 * | | 22 | |
140 * |----+----+----+----+----+ +
141 * | 30 | 31 | 32 | 33 | 34 | |
142 * +----+----+----+----+----+----+
143 *
144 * will log in the console:
145 *
146 * 'A cell at row 1 and column 2'
147 * 'A cell at row 1 and column 4'
148 * 'A cell at row 1 and column 5'
149 * 'A cell at row 2 and column 2'
150 *
151 * To also iterate over spanned cells:
152 *
153 * ```ts
154 * const tableWalker = new TableWalker( table, { row: 1, includeAllSlots: true } );
155 *
156 * for ( const tableSlot of tableWalker ) {
157 * console.log( 'Slot at', tableSlot.row, 'x', tableSlot.column, ':', tableSlot.isAnchor ? 'is anchored' : 'is spanned' );
158 * }
159 * ```
160 *
161 * will log in the console for the table from the previous example:
162 *
163 * 'Cell at 1 x 0 : is spanned'
164 * 'Cell at 1 x 1 : is spanned'
165 * 'Cell at 1 x 2 : is anchored'
166 * 'Cell at 1 x 3 : is spanned'
167 * 'Cell at 1 x 4 : is anchored'
168 * 'Cell at 1 x 5 : is anchored'
169 *
170 * **Note**: Option `row` is a shortcut that sets both `startRow` and `endRow` to the same row.
171 * (Use either `row` or `startRow` and `endRow` but never together). Similarly the `column` option sets both `startColumn`
172 * and `endColumn` to the same column (Use either `column` or `startColumn` and `endColumn` but never together).
173 *
174 * @param table A table over which the walker iterates.
175 * @param options An object with configuration.
176 * @param options.row A row index for which this iterator will output cells. Can't be used together with `startRow` and `endRow`.
177 * @param options.startRow A row index from which this iterator should start. Can't be used together with `row`. Default value is 0.
178 * @param options.endRow A row index at which this iterator should end. Can't be used together with `row`.
179 * @param options.column A column index for which this iterator will output cells.
180 * Can't be used together with `startColumn` and `endColumn`.
181 * @param options.startColumn A column index from which this iterator should start.
182 * Can't be used together with `column`. Default value is 0.
183 * @param options.endColumn A column index at which this iterator should end. Can't be used together with `column`.
184 * @param options.includeAllSlots Also return values for spanned cells. Default value is "false".
185 */
186 constructor(table: Element, options?: TableWalkerOptions);
187 /**
188 * Iterable interface.
189 */
190 [Symbol.iterator](): IterableIterator<TableSlot>;
191 /**
192 * Gets the next table walker's value.
193 *
194 * @returns The next table walker's value.
195 */
196 next(): IteratorResult<TableSlot, undefined>;
197 /**
198 * Marks a row to skip in the next iteration. It will also skip cells from the current row if there are any cells from the current row
199 * to output.
200 *
201 * @param row The row index to skip.
202 */
203 skipRow(row: number): void;
204 /**
205 * Advances internal cursor to the next row.
206 */
207 private _advanceToNextRow;
208 /**
209 * Checks if the current row is over {@link #_endRow}.
210 */
211 private _isOverEndRow;
212 /**
213 * Checks if the current cell is over {@link #_endColumn}
214 */
215 private _isOverEndColumn;
216 /**
217 * A common method for formatting the iterator's output value.
218 *
219 * @param cell The table cell to output.
220 * @param anchorRow The row index of a cell anchor slot.
221 * @param anchorColumn The column index of a cell anchor slot.
222 */
223 private _formatOutValue;
224 /**
225 * Checks if the current slot should be skipped.
226 */
227 private _shouldSkipSlot;
228 /**
229 * Returns the cell element that is spanned over the current cell location.
230 */
231 private _getSpanned;
232 /**
233 * Updates spanned cells map relative to the current cell location and its span dimensions.
234 *
235 * @param cell A cell that is spanned.
236 * @param rowspan Cell height.
237 * @param colspan Cell width.
238 */
239 private _recordSpans;
240 /**
241 * Marks the cell location as spanned by another cell.
242 *
243 * @param row The row index of the cell location.
244 * @param column The column index of the cell location.
245 * @param data A spanned cell details (cell element, anchor row and column).
246 */
247 private _markSpannedCell;
248}
249/**
250 * An object returned by {@link module:table/tablewalker~TableWalker} when traversing table cells.
251 */
252declare class TableSlot {
253 /**
254 * The current table cell.
255 */
256 readonly cell: Element;
257 /**
258 * The row index of a table slot.
259 */
260 readonly row: number;
261 /**
262 * The column index of a table slot.
263 */
264 readonly column: number;
265 /**
266 * The row index of a cell anchor slot.
267 */
268 readonly cellAnchorRow: number;
269 /**
270 * The column index of a cell anchor slot.
271 */
272 readonly cellAnchorColumn: number;
273 /**
274 * The index of the current cell in the parent row.
275 */
276 private readonly _cellIndex;
277 /**
278 * The index of the current row element in the table.
279 */
280 private readonly _rowIndex;
281 /**
282 * The table element.
283 */
284 private readonly _table;
285 /**
286 * Creates an instance of the table walker value.
287 *
288 * @param tableWalker The table walker instance.
289 * @param cell The current table cell.
290 * @param anchorRow The row index of a cell anchor slot.
291 * @param anchorColumn The column index of a cell anchor slot.
292 */
293 constructor(tableWalker: TableWalker, cell: Element, anchorRow: number, anchorColumn: number);
294 /**
295 * Whether the cell is anchored in the current slot.
296 */
297 get isAnchor(): boolean;
298 /**
299 * The width of a cell defined by a `colspan` attribute. If the model attribute is not present, it is set to `1`.
300 */
301 get cellWidth(): number;
302 /**
303 * The height of a cell defined by a `rowspan` attribute. If the model attribute is not present, it is set to `1`.
304 */
305 get cellHeight(): number;
306 /**
307 * The index of the current row element in the table.
308 */
309 get rowIndex(): number;
310 /**
311 * Returns the {@link module:engine/model/position~Position} before the table slot.
312 */
313 getPositionBefore(): Position;
314}
315export type { TableSlot };
316/**
317 * This `TableSlot`'s getter (property) was removed in CKEditor 5 v20.0.0.
318 *
319 * Check out the new `TableWalker`'s API in the documentation.
320 *
321 * @error tableslot-getter-removed
322 * @param getterName
323 */