/** * 修复程序类型 */ export const FIXER_NONE = "-"; export const FIXER_BR = "br"; export const FIXER_BN = "bn"; export const FIXER_BR_DIV = "brToDiv"; export const FIXER_BN_DIV = "bnToDiv"; export const FIXER_ALL = [ FIXER_NONE, FIXER_BR, FIXER_BN, FIXER_BR_DIV, FIXER_BN_DIV, ]; /** * 修复过的标记 */ const fixedSign = "kiss-fixed"; /** * 采用 `br` 换行网站的修复函数 * 目标是将 `br` 替换成 `p` * @param {*} node * @returns */ function brFixer(node, tag = "p") { if (node.hasAttribute(fixedSign)) { return; } node.setAttribute(fixedSign, "true"); const gapTags = ["BR", "WBR"]; const newlineTags = [ "DIV", "UL", "OL", "LI", "H1", "H2", "H3", "H4", "H5", "H6", "P", "HR", "PRE", "TABLE", "BLOCKQUOTE", ]; let html = ""; node.childNodes.forEach(function (child, index) { if (index === 0) { html += `<${tag} class="kiss-p">`; } if (gapTags.indexOf(child.nodeName) !== -1) { html += `<${tag} class="kiss-p">`; } else if (newlineTags.indexOf(child.nodeName) !== -1) { html += `${child.outerHTML}<${tag} class="kiss-p">`; } else if (child.outerHTML) { html += child.outerHTML; } else if (child.textContent) { html += child.textContent; } if (index === node.childNodes.length - 1) { html += ``; } }); node.innerHTML = html; } function brDivFixer(node) { return brFixer(node, "div"); } /** * 目标是将 `\n` 替换成 `p` * @param {*} node * @returns */ function bnFixer(node, tag = "p") { if (node.hasAttribute(fixedSign)) { return; } node.setAttribute(fixedSign, "true"); node.innerHTML = node.innerHTML .split("\n") .map((item) => `<${tag} class="kiss-p">${item || " "}`) .join(""); } function bnDivFixer(node) { return bnFixer(node, "div"); } /** * 查找、监听节点,并执行修复函数 * @param {*} selector * @param {*} fixer * @param {*} rootSelector */ function run(selector, fixer, rootSelector) { const mutaObserver = new MutationObserver(function (mutations) { mutations.forEach(function (mutation) { mutation.addedNodes.forEach(function (addNode) { if (addNode && addNode.querySelectorAll) { addNode.querySelectorAll(selector).forEach(function (node) { fixer(node); }); } }); }); }); let rootNodes = [document]; if (rootSelector) { rootNodes = document.querySelectorAll(rootSelector); } rootNodes.forEach(function (rootNode) { rootNode.querySelectorAll(selector).forEach(function (node) { fixer(node); }); mutaObserver.observe(rootNode, { childList: true, subtree: true, }); }); } /** * 修复程序映射 */ const fixerMap = { [FIXER_BR]: brFixer, [FIXER_BN]: bnFixer, [FIXER_BR_DIV]: brDivFixer, [FIXER_BN_DIV]: bnDivFixer, }; /** * 执行fixer * @param {*} param0 */ export function runFixer(selector, fixer = "-", rootSelector) { try { if (Object.keys(fixerMap).includes(fixer)) { run(selector, fixerMap[fixer], rootSelector); } } catch (err) { console.error(`[kiss-webfix run]: ${err.message}`); } }