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 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 253x 253x 253x 253x 253x 253x 253x 253x 250x 250x 250x 250x 250x 250x 3x 3x 3x 253x 111x 111x 103x 253x 253x | import { applyFormat } from '../utils/applyFormat'; import { applyMetadata } from '../utils/applyMetadata'; import { isGenericRoleElement } from '../../domUtils/isGenericRoleElement'; import { setParagraphNotImplicit } from '../../modelApi/block/setParagraphNotImplicit'; import { stackFormat } from '../utils/stackFormat'; import { unwrap } from '../../domUtils/unwrap'; import type { ContentModelBlockHandler, ContentModelListItem, ModelToDomContext, } from 'roosterjs-content-model-types'; const HtmlRoleAttribute = 'role'; const PresentationRoleValue = 'presentation'; /** * @internal */ export const handleListItem: ContentModelBlockHandler<ContentModelListItem> = ( doc: Document, parent: Node, listItem: ContentModelListItem, context: ModelToDomContext, refNode: Node | null ) => { refNode = context.modelHandlers.list(doc, parent, listItem, context, refNode); const { nodeStack } = context.listFormat; const listParent = nodeStack?.[nodeStack?.length - 1]?.node || parent; const li = doc.createElement('li'); const level = listItem.levels[listItem.levels.length - 1]; // It is possible listParent is the same with parent param. // This happens when outdent a list item to cause it has no list level listParent.insertBefore(li, refNode?.parentNode == listParent ? refNode : null); context.rewriteFromModel.addedBlockElements.push(li); if (level) { applyFormat(li, context.formatAppliers.segment, listItem.formatHolder.format, context); applyFormat(li, context.formatAppliers.listItemThread, level.format, context); // Need to apply metadata after applying listItem format since the list numbers value relies on the result of list thread handling applyMetadata(level, context.metadataAppliers.listItem, listItem.format, context); // Need to apply listItemElement formats after applying metadata since the list numbers value relies on the result of metadata handling applyFormat(li, context.formatAppliers.listItemElement, listItem.format, context); stackFormat(context, listItem.formatHolder.format, () => { context.modelHandlers.blockGroupChildren(doc, li, listItem, context); }); } else { // There is no level for this list item, that means it should be moved out of the list // For each paragraph, make it not implicit so it will have a DIV around it, to avoid more paragraphs connected together listItem.blocks.forEach(setParagraphNotImplicit); context.modelHandlers.blockGroupChildren(doc, li, listItem, context); unwrap(li); } // Add role="presentation" to all generic role elements inside the LI element // This is to make sure the elements are announced correctly by screen readers // when using arrow keys to navigate the list. for (let index = 0; index < li.children.length; index++) { const element = li.children.item(index); if (isGenericRoleElement(element)) { element.setAttribute(HtmlRoleAttribute, PresentationRoleValue); } } context.onNodeCreated?.(listItem, li); return refNode; }; |