import { Arr, Optional } from '@ephox/katamari'; import type { SugarElement } from '../../api/node/SugarElement'; import * as SugarText from '../../api/node/SugarText'; import * as Geometry from '../alien/Geometry'; const locateOffset = (doc: SugarElement, textnode: SugarElement, x: number, y: number, rect: ClientRect | DOMRect): Range => { const rangeForOffset = (o: number) => { const r = doc.dom.createRange(); r.setStart(textnode.dom, o); r.collapse(true); return r; }; const rectForOffset = (o: number) => { const r = rangeForOffset(o); return r.getBoundingClientRect(); }; const length = SugarText.get(textnode).length; const offset = Geometry.searchForPoint(rectForOffset, x, y, rect.right, length); return rangeForOffset(offset); }; const locate = (doc: SugarElement, node: SugarElement, x: number, y: number): Optional => { const r = doc.dom.createRange(); r.selectNode(node.dom); const rects = r.getClientRects(); const foundRect = Arr.findMap(rects, (rect) => Geometry.inRect(rect, x, y) ? Optional.some(rect) : Optional.none()); return foundRect.map((rect) => locateOffset(doc, node, x, y, rect)); }; export { locate };