import { Optional } from '@ephox/katamari'; import type { SugarElement } from '../node/SugarElement'; import * as PredicateFind from '../search/PredicateFind'; import * as Traverse from '../search/Traverse'; import * as Awareness from './Awareness'; const first = (element: SugarElement): Optional> => PredicateFind.descendant(element, Awareness.isCursorPosition); const last = (element: SugarElement): Optional> => descendantRtl(element, Awareness.isCursorPosition); // Note, sugar probably needs some RTL traversals. const descendantRtl: { (scope: SugarElement, predicate: (e: SugarElement) => e is SugarElement): Optional>; (scope: SugarElement, predicate: (e: SugarElement) => boolean): Optional>; } = (scope: SugarElement, predicate: (e: SugarElement) => boolean): Optional> => { const descend = (element: SugarElement): Optional> => { const children = Traverse.children(element); for (let i = children.length - 1; i >= 0; i--) { const child = children[i]; if (predicate(child)) { return Optional.some(child); } const res = descend(child); if (res.isSome()) { return res; } } return Optional.none>(); }; return descend(scope); }; export { first, last };