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;
}
};
};
}