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 | 1x 1x 17x 17x 17x 9x 9x 1x 1x 7x 7x 7x 7x 3x 7x 7x 1x 25x 1x 17x 15x 15x 15x 15x 8x 8x 4x 4x 15x 4x | import { mutateBlock, normalizeContentModel, setParagraphNotImplicit, } from 'roosterjs-content-model-dom'; import type { DeleteResult, FormatContentModelContext, IEditor, ReadonlyContentModelBlockGroup, ReadonlyContentModelDocument, } from 'roosterjs-content-model-types'; /** * @internal * @return True means content is changed, so need to rewrite content model to editor. Otherwise false */ export function handleKeyboardEventResult( editor: IEditor, model: ReadonlyContentModelDocument, rawEvent: KeyboardEvent, result: DeleteResult, context: FormatContentModelContext ): boolean { context.skipUndoSnapshot = true; context.clearModelCache = false; switch (result) { case 'notDeleted': // We have not delete anything, we will let browser handle this event, so that current cached model may be invalid context.clearModelCache = true; // Return false here since we didn't do any change to Content Model, so no need to rewrite with Content Model return false; case 'nothingToDelete': // We known there is nothing to delete, no need to let browser keep handling the event rawEvent.preventDefault(); return false; case 'range': case 'singleChar': // We have deleted what we need from content model, no need to let browser keep handling the event rawEvent.preventDefault(); normalizeContentModel(model); deleteEmptyBlockGroups(model); if (result == 'range') { // A range is about to be deleted, so add an undo snapshot immediately context.skipUndoSnapshot = false; } // Trigger an event to let plugins know the content is about to be changed by Content Model keyboard editing. // So plugins can do proper handling. e.g. UndoPlugin can decide whether take a snapshot before this change happens. editor.triggerEvent('beforeKeyboardEditing', { rawEvent, }); return true; } } /** * @internal */ export function shouldDeleteWord(rawEvent: KeyboardEvent, isMac: boolean) { return ( (isMac && rawEvent.altKey && !rawEvent.metaKey) || (!isMac && rawEvent.ctrlKey && !rawEvent.altKey) ); } /** * @internal */ export function shouldDeleteAllSegmentsBefore(rawEvent: KeyboardEvent) { return rawEvent.metaKey && !rawEvent.altKey; } function deleteEmptyBlockGroups(group: ReadonlyContentModelBlockGroup) { let modified = false; for (let i = group.blocks.length - 1; i >= 0; i--) { const block = group.blocks[i]; if (block.blockType == 'BlockGroup') { deleteEmptyBlockGroups(block); if (block.blocks.length == 0) { mutateBlock(group).blocks.splice(i, 1); modified = true; } } } if (modified) { group.blocks.forEach(setParagraphNotImplicit); } } |