Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | 1x 1x 9x 9x 5x 2x 5x 4x 4x 4x 4x 4x 7x 7x 7x 7x 3x 4x 9x 8x 8x 8x 8x | import { createBr, createParagraph, mutateBlock } from 'roosterjs-content-model-dom';
import type {
ContentModelParagraph,
ReadonlyContentModelBlock,
ReadonlyContentModelBlockGroup,
ReadonlyContentModelDocument,
ReadonlyContentModelTable,
} from 'roosterjs-content-model-types';
/**
* @internal
* After edit table, it maybe in a abnormal state, e.g. selected table cell is removed, or all rows are removed causes no place to put cursor.
* We need to make sure table is in normal state, and there is a place to put cursor.
* @returns a new paragraph that can but put focus in, or undefined if not needed
*/
export function ensureFocusableParagraphForTable(
model: ReadonlyContentModelDocument,
path: ReadonlyContentModelBlockGroup[],
table: ReadonlyContentModelTable
): ContentModelParagraph | undefined {
let paragraph: ContentModelParagraph | undefined;
const firstCell = table.rows.filter(row => row.cells.length > 0)[0]?.cells[0];
if (firstCell) {
// When there is a valid cell to put focus, use it
paragraph = firstCell.blocks.filter(
(block): block is ContentModelParagraph => block.blockType == 'Paragraph'
)[0];
if (!paragraph) {
// If there is not a paragraph under this cell, create one
paragraph = createEmptyParagraph(model);
mutateBlock(firstCell).blocks.push(paragraph);
}
} else {
// No table cell at all, which means the whole table is deleted. So we need to remove it from content model.
let block: ReadonlyContentModelBlock = table;
let parent: ReadonlyContentModelBlockGroup | undefined;
paragraph = createEmptyParagraph(model);
// If the table is the only block of its parent and parent is a FormatContainer, remove the parent as well.
// We need to do this in a loop in case there are multiple layer of FormatContainer that match this case
while ((parent = path.shift())) {
const index = parent.blocks.indexOf(block) ?? -1;
Eif (parent && index >= 0) {
mutateBlock(parent).blocks.splice(index, 1, paragraph);
}
if (
parent.blockGroupType == 'FormatContainer' &&
parent.blocks.length == 1 &&
parent.blocks[0] == paragraph
) {
// If the new paragraph is the only child of parent format container, unwrap parent as well
block = parent;
} else {
// Otherwise, just stop here and keep processing the new paragraph
break;
}
}
}
return paragraph;
}
function createEmptyParagraph(model: ReadonlyContentModelDocument) {
const newPara = createParagraph(false /*isImplicit*/, undefined /*blockFormat*/, model.format);
const br = createBr(model.format);
newPara.segments.push(br);
return newPara;
}
|