UNPKG

unlayer2be

Version:

Unlayer2be is a library which can be used to convert BEE email design to Unlayer email design, or Html to Unlayer design

134 lines (100 loc) 3.83 kB
const CONTENTS = ["P", "HR"]; const INLINES = ["STRONG", "EM", "BR"]; const SUBELEMENTS = ["IMG", "SPAN", "TR", "TD", "TBODY", "TABLE", "A", "P", "H1", "H2", "H3", "H4", "H5", "H6"]; export function parseHtml(html: string): HTMLBodyElement | null { if (typeof window === "undefined") { try { const dom = require("jsdom"); const document = new dom.JSDOM(html).window.document; globalThis.document = document; return document.querySelector("body"); } catch (e: any) { throw new Error(e.message); } } else { return new DOMParser().parseFromString(html, "text/html").querySelector("body"); } } export function parseRows(body: HTMLBodyElement | null) { return Array.from( parseChildren( Array.from(body?.children ?? []) .filter( x => x.tagName.toUpperCase() != "SCRIPT" && x.tagName.toUpperCase() != "STYLE") )); } export function parseChildren(children: any[], isContent = false, parent: any = null): any[] { if ( children?.length == 1 && children?.length == 1 && children[0]?.tagName?.toUpperCase() != "A" && !CONTENTS.includes(children[0]?.tagName.toUpperCase()) && !INLINES.includes(children[0]?.tagName.toUpperCase()) && ((isContent && isSubElement(children[0])) || (isContent && children[0]?.querySelector("img")) || (!isContent))) { return parseChildren( children[0]?.children, isContent, children[0]); } if ( children?.length == 1 && children[0].tagName.toUpperCase() == "A" ) { return Array.from( addContainer(children[0].parentElement).children) .map((x: any) => isSubElement(x) ? addContainer(x) : x); } if (!children?.length && parent) { return Array.from( addContainer(parent).children) .map((x: any) => isSubElement(x) ? addContainer(x) : x); } if (CONTENTS.some(x => Array.from(children) .map(y => y.tagName.toUpperCase()).includes(x))) { return [addContainer(children[0].parentElement)]; } if (INLINES.some(x => Array.from(children) .map(y => y.tagName.toUpperCase()).includes(x))) { return Array.from(children[0].parentElement); } return Array.from(children).map(x => isSubElement(x) ? addContainer(x) : x); } export function isSubElement(element: Element) { return SUBELEMENTS. some(x => (x == element?.tagName?.toUpperCase()) || (x == element?.parentElement?.tagName?.toUpperCase()) ); } export function addContainer(element: Element): any { let container = document.createElement("div"); container.setAttribute("class", `unlayer2be`); container.innerHTML = element.outerHTML; element.parentNode?.replaceChild(container, element); return container; } export function parseColumns(row: Element, hasMultipleCells = false): any[] { return Array.from( hasMultipleCells ? row?.children[0]?.children[0]?.children[0]?.children ?? [] : row?.children).map(x => isSubElement(x) ? addContainer(x) : x); } export function parseInlineStyle(element: Element): any { let style = {}; const style_ = element?.getAttribute("style"); style_?.split(";").forEach(x => { const key = x.split(":")[0]; const value = x.split(":")[1]; Object.assign(style, { [key]: value }); }); return style; }