import { Arr, Optional } from '@ephox/katamari'; import type { Gene } from '../api/Gene'; import * as Detach from './Detach'; import * as Locator from './Locator'; import * as Up from './Up'; const before = (anchor: Gene, item: Gene): void => { anchor.parent.each((parent) => { const index = Locator.indexIn(parent, anchor); const detached = Detach.detach(Up.top(anchor), item).getOr(item); detached.parent = Optional.some(parent); index.each((ind) => { parent.children = parent.children.slice(0, ind).concat([ detached ]).concat(parent.children.slice(ind)); }); }); }; const after = (anchor: Gene, item: Gene): void => { anchor.parent.each((parent) => { const index = Locator.indexIn(parent, anchor); const detached = Detach.detach(Up.top(anchor), item).getOr(item); detached.parent = Optional.some(parent); index.each((ind) => { parent.children = parent.children.slice(0, ind + 1).concat([ detached ]).concat(parent.children.slice(ind + 1)); }); }); }; const append = (parent: Gene, item: Gene): void => { const detached = Detach.detach(Up.top(parent), item).getOr(item); parent.children = parent.children || []; parent.children = parent.children.concat([ detached ]); detached.parent = Optional.some(parent); }; const appendAll = (parent: Gene, items: Gene[]): void => { Arr.map(items, (item) => { append(parent, item); }); }; const afterAll = (anchor: Gene, items: Gene[]): void => { anchor.parent.each((parent) => { const index = Locator.indexIn(parent, anchor); const detached = Arr.map(items, (item) => { const ditem = Detach.detach(Up.top(anchor), item).getOr(item); ditem.parent = Optional.some(parent); return ditem; }); index.each((ind) => { parent.children = parent.children.slice(0, ind + 1).concat(detached).concat(parent.children.slice(ind + 1)); }); }); }; const prepend = (parent: Gene, item: Gene): void => { const detached = Detach.detach(Up.top(parent), item).getOr(item); parent.children = parent.children || []; parent.children = [ detached ].concat(parent.children); detached.parent = Optional.some(parent); }; const wrap = (anchor: Gene, wrapper: Gene): void => { // INVESTIGATE: At this stage, mutation is necessary to act like the DOM anchor.parent.each((parent) => { wrapper.parent = Optional.some(parent); parent.children = Arr.map(parent.children || [], (c) => { return c === anchor ? wrapper : c; }); wrapper.children = [ anchor ]; anchor.parent = Optional.some(wrapper); }); }; export { before, after, afterAll, append, appendAll, prepend, wrap };