import { flattenDeep } from "lodash-es"; let res = []; /** * * @param {HTMLDivElement} editor */ export function toJSON(editor) { // console.log(editor.innerHTML); res = []; for (const e of [...editor.childNodes]) { toSection(e); } const newRes = []; for (let section of res) { section = flattenElement(section); let newSection = []; for (const b of section) { const toB = toBlock(b); if (toB) newSection.push(toB); } if (newSection.length === 0) { // 空行特殊处理 newSection = [{ type: "text", value: " ", param: null }]; } newRes.push({ blocks: newSection }); } res = { sections: newRes }; // console.log(res); // console.log(JSON.stringify(res)); // console.log(JSON.stringify(res, null, 2)); return JSON.stringify(res, null, 2); } /** * * @param {Node} e */ function toSection(e) { if (e.nodeType == Node.ELEMENT_NODE && e.nodeName === "DIV") { res.push(e.childNodes); } else if (e.nodeType == Node.TEXT_NODE) { res.push([e]); } else { console.log("toSection: 非div, 非TEXT", e); } } /** * * @param {Node[]} section */ function flattenElement(section) { section = [...section]; // console.log(section); for (let i = 0; i < section.length; i++) { if (section[i].hasChildNodes()) { section[i] = [...section[i].childNodes]; for (let j = 0; j < section[i].length; j++) { if (section[i][j].hasChildNodes()) { section[i][j] = [...section[i][j].childNodes]; for (let k = 0; k < section[i][j].length; k++) { if (section[i][j][k].hasChildNodes()) { section[i][j][k] = [...section[i][j][k].childNodes]; } } } } } } section = flattenDeep(section); return section; } /** * * @param {Node} e * @param {String} tag */ function checkAncestorElementTag(e, tag) { for (let i = 0; i < 3; i++) { if (e.parentElement.nodeName === tag) { return true; } else { e = e.parentElement; } } return false; } /** * * @param {Node} e */ function toBlock(e) { let block = {}; if (e.nodeType === Node.TEXT_NODE) { block.type = "text"; block.value = e.textContent; block.param = {}; // block.param.italic = // window.getComputedStyle(e.parentElement).fontStyle === "italic"; // block.param.bold = // window.getComputedStyle(e.parentElement).fontWeight > 400; // block.param.underline = // window.getComputedStyle(e.parentElement).textDecorationLine === // "underline"; block.param.italic = checkAncestorElementTag(e, "I"); block.param.bold = checkAncestorElementTag(e, "B"); block.param.underline = checkAncestorElementTag(e, "U"); // console.log(block.param); const allFalse = Object.values(block.param).every((v) => v === false); // console.log(allFalse); if (allFalse) { block.param = null; } // } else if (e.nodeType == Node.ELEMENT_NODE && e.nodeName === "SPAN") { // block.type = "text"; // block.value = e.textContent; // block.param = {}; } else if (e.nodeType == Node.ELEMENT_NODE && e.nodeName === "U") { block.type = "text"; block.value = e.textContent; block.param = { underline: true }; } else if (e.nodeType == Node.ELEMENT_NODE && e.nodeName === "B") { block.type = "text"; block.value = e.textContent; block.param = { bold: true }; } else if (e.nodeType == Node.ELEMENT_NODE && e.nodeName === "I") { block.type = "text"; block.value = e.textContent; block.param = { italic: true }; } else if (e.nodeType == Node.ELEMENT_NODE && e.nodeName === "IMG") { block.type = "image"; block.value = e.src; block.param = { width: e.width, height: e.height }; } else if (e.nodeType == Node.ELEMENT_NODE && e.nodeName === "BR") { block.type = "text"; block.value = ""; block.param = null; } else { console.log("toBlock: 非法", e); } if (block.type === "text" && block.value === "") { block = null; // 返回null的block,从json中剔除 } return block; }