import type { Optional } from '@ephox/katamari'; import ClosestOrAncestor from '../../impl/ClosestOrAncestor'; import type { SugarElement } from '../node/SugarElement'; import * as PredicateFind from './PredicateFind'; import * as Selectors from './Selectors'; // TODO: An internal SelectorFilter module that doesn't SugarElement.fromDom() everything const first = (selector: string): Optional> => Selectors.one(selector); const ancestor = (scope: SugarElement, selector: string, isRoot?: (e: SugarElement) => boolean): Optional> => PredicateFind.ancestor(scope, (e): e is SugarElement => Selectors.is(e, selector), isRoot); const sibling = (scope: SugarElement, selector: string): Optional> => PredicateFind.sibling(scope, (e): e is SugarElement => Selectors.is(e, selector)); const child = (scope: SugarElement, selector: string): Optional> => PredicateFind.child(scope, (e): e is SugarElement => Selectors.is(e, selector)); const descendant = (scope: SugarElement, selector: string): Optional> => Selectors.one(selector, scope); // Returns Some(closest ancestor element (sugared)) matching 'selector' up to isRoot, or None() otherwise const closest = (scope: SugarElement, selector: string, isRoot?: (e: SugarElement) => boolean): Optional> => { const is = (element: SugarElement, selector: string): element is SugarElement => Selectors.is(element, selector); return ClosestOrAncestor(is, ancestor, scope, selector, isRoot); }; export { first, ancestor, sibling, child, descendant, closest };