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 | 1x 1x 1x 24x 24x 34x 17x 17x 17x 17x 17x 82x 41x 41x 41x 41x 7x 34x 34x 17x | import { isNodeOfType } from '../isNodeOfType'; import { normalizeRect } from '../normalizeRect'; import type { DOMInsertPoint, Rect } from 'roosterjs-content-model-types'; /** * Get bounding rect of the given DOM insert point * @param doc The document object * @param pos The input DOM insert point */ export function getDOMInsertPointRect(doc: Document, pos: DOMInsertPoint): Rect | null { const range = doc.createRange(); return ( tryGetRectFromPos(pos, range) ?? // 1. try get from the pos directly using getBoundingClientRect or getClientRects tryGetRectFromPos((pos = normalizeInsertPoint(pos)), range) ?? // 2. try get normalized pos, this can work when insert point is inside text node tryGetRectFromNode(pos.node) // 3. fallback to node rect using getBoundingClientRect ); } function normalizeInsertPoint(pos: DOMInsertPoint) { let { node, offset } = pos; while (node.lastChild) { Iif (offset == node.childNodes.length) { node = node.lastChild; offset = node.childNodes.length; } else { node = node.childNodes[offset]; offset = 0; } } return { node, offset }; } function tryGetRectFromPos(pos: DOMInsertPoint, range: Range): Rect | null { const { node, offset } = pos; range.setStart(node, offset); range.setEnd(node, offset); const rect = normalizeRect(range.getBoundingClientRect()); if (rect) { return rect; } else { const rects = range.getClientRects && range.getClientRects(); return rects && rects.length == 1 ? normalizeRect(rects[0]) : null; } } function tryGetRectFromNode(node: Node) { return isNodeOfType(node, 'ELEMENT_NODE') && node.getBoundingClientRect ? normalizeRect(node.getBoundingClientRect()) : null; } |