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 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 | 1x 1x 61x 61x 80x 80x 80x 78x 78x 43x 16x 16x 2x 14x 12x 12x 2x 2x 29x 35x 10x 10x 10x 10x 12x 10x 10x 10x 4x 6x 25x 13x 13x 14x | import { isGeneralSegment } from 'roosterjs-content-model-dom'; import type { ContentModelParagraph, ReadonlyContentModelBlock, ReadonlyContentModelBlockGroup, ReadonlyContentModelSegment, } from 'roosterjs-content-model-types'; /** * @internal */ export type BlockAndPath = { /** * The sibling block */ block: ReadonlyContentModelBlock; /** * Path of this sibling block */ path: ReadonlyContentModelBlockGroup[]; /** * If the input block is under a general segment, it is possible there are sibling segments under the same paragraph. * Use this property to return the sibling sibling under the same paragraph */ siblingSegment?: ReadonlyContentModelSegment; }; /** * @internal */ export type ReadonlyBlockAndPath = { /** * The sibling block */ block: ReadonlyContentModelBlock; /** * Path of this sibling block */ path: ReadonlyContentModelBlockGroup[]; /** * If the input block is under a general segment, it is possible there are sibling segments under the same paragraph. * Use this property to return the sibling sibling under the same paragraph */ siblingSegment?: ReadonlyContentModelSegment; }; /** * @internal */ export function getLeafSiblingBlock( path: ReadonlyContentModelBlockGroup[], block: ReadonlyContentModelBlock, isNext: boolean ): BlockAndPath | null; /** * @internal (Readonly) */ export function getLeafSiblingBlock( path: ReadonlyContentModelBlockGroup[], block: ReadonlyContentModelBlock, isNext: boolean ): ReadonlyBlockAndPath | null; export function getLeafSiblingBlock( path: ReadonlyContentModelBlockGroup[], block: ReadonlyContentModelBlock, isNext: boolean ): ReadonlyBlockAndPath | null { const newPath = [...path]; while (newPath.length > 0) { const group = newPath[0]; const index = group.blocks.indexOf(block); if (index < 0) { break; } let nextBlock = group.blocks[index + (isNext ? 1 : -1)]; if (nextBlock) { while (nextBlock.blockType == 'BlockGroup') { const child = nextBlock.blocks[isNext ? 0 : nextBlock.blocks.length - 1]; if (!child) { return { block: nextBlock, path: newPath }; } else if (child.blockType != 'BlockGroup') { newPath.unshift(nextBlock); return { block: child, path: newPath }; } else { newPath.unshift(nextBlock); nextBlock = child; } } return { block: nextBlock, path: newPath }; } else if (isGeneralSegment(group)) { // For general segment, we need to check if there is sibling segment under the same paragraph // First let's find the parent paragraph of this segment newPath.shift(); let segmentIndex = -1; const segment = group; const para = newPath[0]?.blocks.find( x => x.blockType == 'Paragraph' && (segmentIndex = x.segments.indexOf(segment)) >= 0 ) as ContentModelParagraph; Eif (para) { // Now we have found the parent paragraph, so let's check if it has a sibling segment const siblingSegment = para.segments[segmentIndex + (isNext ? 1 : -1)]; if (siblingSegment) { // Return this block, path and segment since we have found it return { block: para, path: newPath, siblingSegment }; } else { // No sibling segment, let's keep go upper level block = para; } } else { // Parent sibling is not found (in theory this should never happen), just return null break; } } else if (group.blockGroupType != 'Document' && group.blockGroupType != 'TableCell') { newPath.shift(); block = group; } else { break; } } return null; } |