@ckeditor/ckeditor5-table
Version:
Table feature for CKEditor 5.
50 lines (49 loc) • 2.25 kB
JavaScript
/**
* @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved.
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
*/
import TableWalker from '../tablewalker.js';
/**
* A table headings refresh handler which marks the table cells or rows in the differ to have it re-rendered
* if the headings attribute changed.
*
* Table heading rows and heading columns are represented in the model by a `headingRows` and `headingColumns` attributes.
*
* When table headings attribute changes, all the cells/rows are marked to re-render to change between `<td>` and `<th>`.
*/
export default function tableHeadingsRefreshHandler(model, editing) {
const differ = model.document.differ;
for (const change of differ.getChanges()) {
let table;
let isRowChange = false;
if (change.type == 'attribute') {
const element = change.range.start.nodeAfter;
if (!element || !element.is('element', 'table')) {
continue;
}
if (change.attributeKey != 'headingRows' && change.attributeKey != 'headingColumns') {
continue;
}
table = element;
isRowChange = change.attributeKey == 'headingRows';
}
else if (change.name == 'tableRow' || change.name == 'tableCell') {
table = change.position.findAncestor('table');
isRowChange = change.name == 'tableRow';
}
if (!table) {
continue;
}
const headingRows = table.getAttribute('headingRows') || 0;
const headingColumns = table.getAttribute('headingColumns') || 0;
const tableWalker = new TableWalker(table);
for (const tableSlot of tableWalker) {
const isHeading = tableSlot.row < headingRows || tableSlot.column < headingColumns;
const expectedElementName = isHeading ? 'th' : 'td';
const viewElement = editing.mapper.toViewElement(tableSlot.cell);
if (viewElement && viewElement.is('element') && viewElement.name != expectedElementName) {
editing.reconvertItem((isRowChange ? tableSlot.cell.parent : tableSlot.cell));
}
}
}
}