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 | 1x 1x 32x 32x 64x 64x 32x 32x 32x 32x 6x 6x 6x 2x 2x 2x 4x 2x 2x 2x 1x 6x 1x 6x 10x 1x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x | import { unwrapBlock, getClosestAncestorBlockGroupIndex, createFormatContainer, mutateBlock, } from 'roosterjs-content-model-dom'; import type { DeleteSelectionStep, ReadonlyContentModelBlockGroup, ReadonlyContentModelFormatContainer, ReadonlyContentModelParagraph, ShallowMutableContentModelFormatContainer, ShallowMutableContentModelParagraph, } from 'roosterjs-content-model-types'; /** * @internal */ export const deleteEmptyQuote: DeleteSelectionStep = context => { const { deleteResult } = context; Eif ( deleteResult == 'nothingToDelete' || deleteResult == 'notDeleted' || deleteResult == 'range' ) { const { insertPoint, formatContext } = context; const { path, paragraph } = insertPoint; const rawEvent = formatContext?.rawEvent as KeyboardEvent; const index = getClosestAncestorBlockGroupIndex( path, ['FormatContainer'], ['TableCell', 'ListItem'] ); const quote = path[index]; if (quote && quote.blockGroupType === 'FormatContainer' && quote.tagName == 'blockquote') { const parent = path[index + 1]; const quoteBlockIndex = parent.blocks.indexOf(quote); if (isEmptyQuote(quote)) { unwrapBlock(parent, quote); rawEvent?.preventDefault(); context.deleteResult = 'range'; } else if ( rawEvent?.key === 'Enter' && quote.blocks.indexOf(paragraph) >= 0 && isEmptyParagraph(paragraph) ) { insertNewLine(mutateBlock(quote), parent, quoteBlockIndex, paragraph); rawEvent?.preventDefault(); context.deleteResult = 'range'; } } } }; const isEmptyQuote = (quote: ReadonlyContentModelFormatContainer) => { return ( quote.blocks.length === 1 && quote.blocks[0].blockType === 'Paragraph' && isEmptyParagraph(quote.blocks[0]) ); }; const isEmptyParagraph = (paragraph: ReadonlyContentModelParagraph) => { return paragraph.segments.every( s => s.segmentType === 'SelectionMarker' || s.segmentType === 'Br' ); }; const insertNewLine = ( quote: ShallowMutableContentModelFormatContainer, parent: ReadonlyContentModelBlockGroup, quoteIndex: number, paragraph: ShallowMutableContentModelParagraph ) => { const paraIndex = quote.blocks.indexOf(paragraph); Eif (paraIndex >= 0) { const mutableParent = mutateBlock(parent); Eif (paraIndex < quote.blocks.length - 1) { const newQuote: ShallowMutableContentModelFormatContainer = createFormatContainer( quote.tagName, quote.format ); newQuote.blocks.push( ...quote.blocks.splice(paraIndex + 1, quote.blocks.length - paraIndex - 1) ); mutableParent.blocks.splice(quoteIndex + 1, 0, newQuote); } mutableParent.blocks.splice(quoteIndex + 1, 0, paragraph); quote.blocks.splice(paraIndex, 1); Iif (quote.blocks.length == 0) { mutableParent.blocks.splice(quoteIndex, 0); } } }; |