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 | 1x 1x 1x 1x 1x 18x 18x 18x 18x 60x 60x 48x 12x 18x 1x 31x 31x 12x 12x 3x 3x 3x 1x 16x 8x 8x 6x 6x 2x 4x 1x 8x 8x 8x 16x 8x 1x 7x 13x 13x 6x 6x 7x 7x 7x | import { mutateSegment } from 'roosterjs-content-model-dom'; import type { ContentModelTable, InsertPoint, ShallowMutableContentModelListItem, ShallowMutableContentModelParagraph, } from 'roosterjs-content-model-types'; const EN_SPACE = '\u2002'; const REGULAR_SPACE = '\u0020'; const NON_BREAK_SPACES = '\u00A0'; /** * @internal */ export const IndentStepInPixel = 40; function countTabsSpaces(text: string) { const spaces = countSpacesBeforeText(text); const tabSpaces = Math.floor(spaces / 4); return tabSpaces; } function countSpacesBeforeText(str: string) { let count = 0; for (const char of str) { if (char === EN_SPACE || char === NON_BREAK_SPACES || char == REGULAR_SPACE) { count++; } else { break; } } return count; } /** * @internal */ export function adjustListIndentation(listItem: ShallowMutableContentModelListItem) { const block = listItem.blocks[0]; if ( block.blockType == 'Paragraph' && block.segments.length > 0 && block.segments[0].segmentType == 'Text' ) { const tabSpaces = countTabsSpaces(block.segments[0].text); if (tabSpaces > 0) { mutateSegment(block, block.segments[0], textSegment => { textSegment.text = textSegment.text.substring(tabSpaces * 4); }); listItem.levels[0].format.marginLeft = tabSpaces * IndentStepInPixel + 'px'; } } } /** * @internal */ export function adjustTableIndentation(insertPoint: InsertPoint, table: ContentModelTable) { const { paragraph, marker } = insertPoint; const indentationMargin = getTableIndentation(paragraph); if (indentationMargin) { insertPoint.paragraph.segments = [marker]; if (insertPoint.paragraph.format.direction == 'rtl') { table.format.marginRight = indentationMargin * IndentStepInPixel + 'px'; } else { table.format.marginLeft = indentationMargin * IndentStepInPixel + 'px'; } } } const getTableIndentation = (paragraph: ShallowMutableContentModelParagraph) => { let tabsNumber = 0; const segments = paragraph.segments; const isEmptyLine = paragraph.segments.every( s => (s.segmentType == 'Text' && s.text.trim().length == 0) || s.segmentType == 'SelectionMarker' || s.segmentType == 'Br' ); if (!isEmptyLine) { return; } let numberOfSegments = 0; for (const seg of segments) { if (seg.segmentType === 'Text') { tabsNumber = tabsNumber + countTabsSpaces(seg.text); numberOfSegments++; } else { break; } } // Text segments must be >= (total segments - 2) to apply margin. // If not, the selection marker is likely between texts segment, so skip margin adjustment. Eif (segments.length - 2 <= numberOfSegments) { return tabsNumber; } return; }; |