import { ChildEnumerator, descendentElementIterator } from "@web-atoms/core/dist/web/core/AtomUI"; export const checkAnyParent = (check: (e: HTMLElement) => boolean) => (e: HTMLElement) => { while (e) { if (check(e)) { return true; } e = e.parentElement; } return false; }; export interface IRangeUpdate { range: Range; check: (e: HTMLElement) => boolean; update: (e: HTMLElement, v?: any) => HTMLElement; value?: any; } export interface IRangeCommand { check: (e: HTMLElement) => boolean; update: (e: HTMLElement, v?: any) => HTMLElement; value?: any; } export default class RangeEditor { public static updateAttribute(range: Range, name: string, value: string, anyParent: boolean = true) { return this.updateRange({ range, check: anyParent ? checkAnyParent((e) => e.getAttribute(name) === value) : (e) => e.getAttribute(name) === value, update: (e) => (e.setAttribute(name, value), e) }) } public static checkRange( { range, check, }: IRangeUpdate ) { const root = range.startContainer.nodeType !== Node.ELEMENT_NODE ? range.startContainer.parentElement : range.startContainer as HTMLElement; return check(root); } public static updateRange( { range, check, update, value }: IRangeUpdate ) { } } const updateAttribute = (name: string, value: string, anyParent = true) => ({ update: (e: HTMLElement, v = value) => (e.setAttribute(name, v), e), check: anyParent ? checkAnyParent((e: HTMLElement) => e.getAttribute(name) === value) : (e: HTMLElement) => e.getAttribute(name) === value }); const updateStyle = (name: keyof CSSStyleDeclaration, value: string, anyParent = true) => ({ update: (e: HTMLElement, v = value) => (e.style[name as any] = v, e), check: anyParent ? checkAnyParent((e: HTMLElement) => e.style[name as any] === value) : (e: HTMLElement) => e.style[name as any] === value }); export const RangeEditorCommands: Record = { bold: updateStyle("fontWeight", "bold"), italic: updateStyle("fontStyle", "italic"), underline: updateStyle("textDecoration", "underline"), strikeThrough: updateStyle("textDecoration", "line-through"), foreColor: { check: () => false, update: (e, value) => { e.style.color = value; return e; } }, removeFormat: { check: () => false, update: (e) => { e.removeAttribute("style"); return e; } } };