import { Fun, Optional, Type } from '@ephox/katamari'; import { SugarElement } from '../node/SugarElement'; const ensureIsRoot = (isRoot?: (e: SugarElement) => boolean) => Type.isFunction(isRoot) ? isRoot : Fun.never; const ancestor = (scope: SugarElement, transform: (e: SugarElement) => Optional, isRoot?: (e: SugarElement) => boolean): Optional => { let element = scope.dom; const stop = ensureIsRoot(isRoot); while (element.parentNode) { element = element.parentNode; const el = SugarElement.fromDom(element); const transformed = transform(el); if (transformed.isSome()) { return transformed; } else if (stop(el)) { break; } } return Optional.none(); }; const closest = (scope: SugarElement, transform: (e: SugarElement) => Optional, isRoot?: (e: SugarElement) => boolean): Optional => { const current = transform(scope); const stop = ensureIsRoot(isRoot); return current.orThunk(() => stop(scope) ? Optional.none() : ancestor(scope, transform, stop)); }; export { ancestor, closest };