import { Arr, Unicode } from '@ephox/katamari'; import { Attribute, Insert, Remove, SelectorFilter, SugarElement, SugarNode, SugarText, Traverse } from '@ephox/sugar'; import * as ElementType from './ElementType'; const getLastChildren = (elm: SugarElement): SugarElement[] => { const children: SugarElement[] = []; let rawNode: Node | null = elm.dom; while (rawNode) { children.push(SugarElement.fromDom(rawNode)); rawNode = rawNode.lastChild; } return children; }; const removeTrailingBr = (elm: SugarElement): void => { const allBrs = SelectorFilter.descendants(elm, 'br'); const brs = Arr.filter(getLastChildren(elm).slice(-1), ElementType.isBr); if (allBrs.length === brs.length) { Arr.each(brs, Remove.remove); } }; const createPaddingBr = (): SugarElement => { const br = SugarElement.fromTag('br'); Attribute.set(br, 'data-mce-bogus', '1'); return br; }; const fillWithPaddingBr = (elm: SugarElement): void => { Remove.empty(elm); Insert.append(elm, createPaddingBr()); }; const isPaddingContents = (elm: SugarElement): boolean => { return SugarNode.isText(elm) ? SugarText.get(elm) === Unicode.nbsp : ElementType.isBr(elm); }; const isPaddedElement = (elm: SugarElement): boolean => { return Arr.filter(Traverse.children(elm), isPaddingContents).length === 1; }; const trimBlockTrailingBr = (elm: SugarElement): void => { Traverse.lastChild(elm).each((lastChild) => { Traverse.prevSibling(lastChild).each((lastChildPrevSibling) => { if (ElementType.isBlock(elm) && ElementType.isBr(lastChild) && ElementType.isBlock(lastChildPrevSibling)) { Remove.remove(lastChild); } }); }); }; export { createPaddingBr, removeTrailingBr, fillWithPaddingBr, isPaddedElement, trimBlockTrailingBr };