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 29x 29x 58x 58x 29x 29x 29x 29x 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); } } }; |