export function makeCreateRangeSelectorMatcher()

in packages/dom/src/range/match.ts [98:127]


export function makeCreateRangeSelectorMatcher(
  createMatcher: <T extends Selector, TMatch extends Node | Range>(
    selector: T,
  ) => Matcher<Node | Range, TMatch>,
): (selector: RangeSelector) => Matcher<Node | Range, Range> {
  return function createRangeSelectorMatcher(selector) {
    const startMatcher = createMatcher(selector.startSelector);
    const endMatcher = createMatcher(selector.endSelector);

    return async function* matchAll(scope) {
      const startMatches = startMatcher(scope);
      const endMatches = endMatcher(scope);

      const pairs = cartesian(startMatches, endMatches);

      for await (let [start, end] of pairs) {
        start = toRange(start);
        end = toRange(end);

        const result = ownerDocument(scope).createRange();
        result.setStart(start.startContainer, start.startOffset);
        // Note that a RangeSelector’s match *excludes* the endSelector’s match,
        // hence we take the end’s startContainer & startOffset.
        result.setEnd(end.startContainer, end.startOffset);

        if (!result.collapsed) yield result;
      }
    };
  };
}