import { Optional } from '@ephox/katamari'; import type { HTMLElementFullTagNameMap } from '../../alien/DomTypes'; interface SugarElement { readonly dom: T; } const fromHtml = (html: string, scope?: Document | null): SugarElement => { const doc = scope || document; const div = doc.createElement('div'); div.innerHTML = html; if (!div.hasChildNodes() || div.childNodes.length > 1) { const message = 'HTML does not have a single root node'; // eslint-disable-next-line no-console console.error(message, html); throw new Error(message); } return fromDom(div.childNodes[0] as unknown as E); }; const fromTag: { (tag: K, scope?: Document | null): SugarElement; (tag: string, scope?: Document | null): SugarElement; } = (tag: string, scope?: Document | null): SugarElement => { const doc = scope || document; const node = doc.createElement(tag); return fromDom(node); }; const fromText = (text: string, scope?: Document | null): SugarElement => { const doc = scope || document; const node = doc.createTextNode(text); return fromDom(node); }; const fromDom = (node: T): SugarElement => { // TODO: Consider removing this check, but left atm for safety if (node === null || node === undefined) { throw new Error('Node cannot be null or undefined'); } return { dom: node }; }; const fromPoint = (docElm: SugarElement, x: number, y: number): Optional> => Optional.from(docElm.dom.elementFromPoint(x, y)).map(fromDom); // tslint:disable-next-line:variable-name const SugarElement = { fromHtml, fromTag, fromText, fromDom, fromPoint }; export { SugarElement };