UNPKG

2.02 kBJavaScriptView 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 */
5import { isSingleParagraphWithoutAttributes } from './downcast';
6/**
7 * A table cell refresh handler which marks the table cell in the differ to have it re-rendered.
8 *
9 * Model `paragraph` inside a table cell can be rendered as `<span>` or `<p>`. It is rendered as `<span>` if this is the only block
10 * element in that table cell and it does not have any attributes. It is rendered as `<p>` otherwise.
11 *
12 * When table cell content changes, for example a second `paragraph` element is added, we need to ensure that the first `paragraph` is
13 * re-rendered so it changes from `<span>` to `<p>`. The easiest way to do it is to re-render the entire table cell.
14 */
15export default function tableCellRefreshHandler(model, editing) {
16 const differ = model.document.differ;
17 // Stores cells to be refreshed, so the table cell will be refreshed once for multiple changes.
18 const cellsToCheck = new Set();
19 for (const change of differ.getChanges()) {
20 const parent = change.type == 'attribute' ? change.range.start.parent : change.position.parent;
21 if (parent.is('element', 'tableCell')) {
22 cellsToCheck.add(parent);
23 }
24 }
25 for (const tableCell of cellsToCheck.values()) {
26 const paragraphsToRefresh = Array.from(tableCell.getChildren())
27 .filter(child => shouldRefresh(child, editing.mapper));
28 for (const paragraph of paragraphsToRefresh) {
29 editing.reconvertItem(paragraph);
30 }
31 }
32}
33/**
34 * Check if given model element needs refreshing.
35 */
36function shouldRefresh(child, mapper) {
37 if (!child.is('element', 'paragraph')) {
38 return false;
39 }
40 const viewElement = mapper.toViewElement(child);
41 if (!viewElement) {
42 return false;
43 }
44 return isSingleParagraphWithoutAttributes(child) !== viewElement.is('element', 'span');
45}