import type { Universe } from '@ephox/boss'; import { Arr, Fun } from '@ephox/katamari'; import * as Extract from '../api/general/Extract'; import { OrphanText } from '../wrap/OrphanText'; import * as Parents from './Parents'; const index = (universe: Universe, items: E[], item: E) => { return Arr.findIndex(items, Fun.curry(universe.eq, item)); }; const order = (items: E[], a: number, delta1: number, b: number, delta2: number) => { return a < b ? items.slice(a + delta1, b + delta2) : items.slice(b + delta2, a + delta1); }; /** * Returns a flat array of text nodes between two defined nodes. * * Deltas are a broken concept. They control whether the item passed is included in the result. */ const range = (universe: Universe, item1: E, delta1: number, item2: E, delta2: number): E[] => { if (universe.eq(item1, item2)) { return [ item1 ]; } return Parents.common(universe, item1, item2).fold(() => { return []; // no common parent, therefore no intervening path. How does this clash with Path in robin? }, (parent) => { const items = [ parent ].concat(Extract.all(universe, parent, Fun.never)); const start = index(universe, items, item1); const finish = index(universe, items, item2); const result = start.bind((startIndex) => { return finish.map((finishIndex) => { return order(items, startIndex, delta1, finishIndex, delta2); }); }).getOr([]); const orphanText = OrphanText(universe); return Arr.filter(result, orphanText.validateText); }); }; export { range };