diff --git a/src/utils/enhance-content.js b/src/utils/enhance-content.js index 97077c8f..b6a7a807 100644 --- a/src/utils/enhance-content.js +++ b/src/utils/enhance-content.js @@ -10,22 +10,20 @@ function _enhanceContent(content, opts = {}) { const dom = document.createElement('div'); dom.innerHTML = enhancedContent; const hasLink = / { link.setAttribute('target', '_blank'); }); // Remove all classes except `u-url`, `mention`, `hashtag` - const links = Array.from(dom.querySelectorAll('a[class]')); + const links = dom.querySelectorAll('a[class]'); links.forEach((link) => { - Array.from(link.classList).forEach((c) => { + link.classList.forEach((c) => { if (!whitelistLinkClasses.includes(c)) { link.classList.remove(c); } @@ -35,7 +33,7 @@ function _enhanceContent(content, opts = {}) { // Add 'has-url-text' to all links that contains a url if (hasLink) { - const links = Array.from(dom.querySelectorAll('a[href]')); + const links = dom.querySelectorAll('a[href]'); links.forEach((link) => { if (/^https?:\/\//i.test(link.textContent.trim())) { link.classList.add('has-url-text'); @@ -45,7 +43,7 @@ function _enhanceContent(content, opts = {}) { // Spanify un-spanned mentions if (hasLink) { - const links = Array.from(dom.querySelectorAll('a[href]')); + const links = dom.querySelectorAll('a[href]'); const usernames = []; links.forEach((link) => { const text = link.innerText.trim(); @@ -56,8 +54,8 @@ function _enhanceContent(content, opts = {}) { const [_, username, domain] = text.split('@'); if (!hasChildren) { if ( - !usernames.find(([u]) => u === username) || - usernames.find(([u, d]) => u === username && d === domain) + !usernames.some(([u]) => u === username) || + usernames.some(([u, d]) => u === username && d === domain) ) { link.innerHTML = `@${username}`; usernames.push([username, domain]); @@ -79,7 +77,7 @@ function _enhanceContent(content, opts = {}) { // ====== // Convert :shortcode: to let textNodes; - if (enhancedContent.indexOf(':') !== -1) { + if (enhancedContent.includes(':')) { textNodes = extractTextNodes(dom); textNodes.forEach((node) => { let html = node.nodeValue @@ -90,8 +88,8 @@ function _enhanceContent(content, opts = {}) { html = emojifyText(html, emojis); } fauxDiv.innerHTML = html; - const nodes = Array.from(fauxDiv.childNodes); - node.replaceWith(...nodes); + // const nodes = [...fauxDiv.childNodes]; + node.replaceWith(...fauxDiv.childNodes); }); } @@ -99,7 +97,7 @@ function _enhanceContent(content, opts = {}) { // =========== // Convert ```code``` to
code
if (hasCodeBlock) { - const blocks = Array.from(dom.querySelectorAll('p')).filter((p) => + const blocks = [...dom.querySelectorAll('p')].filter((p) => /^```[^]+```$/g.test(p.innerText.trim()), ); blocks.forEach((block) => { @@ -113,7 +111,7 @@ function _enhanceContent(content, opts = {}) { // Convert multi-paragraph code blocks to
code
if (hasCodeBlock) { - const paragraphs = Array.from(dom.querySelectorAll('p')); + const paragraphs = [...dom.querySelectorAll('p')]; // Filter out paragraphs with ``` in beginning only const codeBlocks = paragraphs.filter((p) => /^```/g.test(p.innerText)); // For each codeBlocks, get all paragraphs until the last paragraph with ``` at the end only @@ -153,7 +151,7 @@ function _enhanceContent(content, opts = {}) { // INLINE CODE // =========== // Convert `code` to code - if (enhancedContent.indexOf('`') !== -1) { + if (enhancedContent.includes('`')) { textNodes = extractTextNodes(dom); textNodes.forEach((node) => { let html = node.nodeValue @@ -164,8 +162,8 @@ function _enhanceContent(content, opts = {}) { html = html.replaceAll(/(`[^]+?`)/g, '$1'); } fauxDiv.innerHTML = html; - const nodes = Array.from(fauxDiv.childNodes); - node.replaceWith(...nodes); + // const nodes = [...fauxDiv.childNodes]; + node.replaceWith(...fauxDiv.childNodes); }); } @@ -188,53 +186,53 @@ function _enhanceContent(content, opts = {}) { ); } fauxDiv.innerHTML = html; - const nodes = Array.from(fauxDiv.childNodes); - node.replaceWith(...nodes); + // const nodes = [...fauxDiv.childNodes]; + node.replaceWith(...fauxDiv.childNodes); }); } // HASHTAG STUFFING // ================ // Get the

that contains a lot of hashtags, add a class to it - if (enhancedContent.indexOf('#') !== -1) { + if (enhancedContent.includes('#')) { let prevIndex = null; - const hashtagStuffedParagraphs = Array.from( - dom.querySelectorAll('p'), - ).filter((p, index) => { - let hashtagCount = 0; - for (let i = 0; i < p.childNodes.length; i++) { - const node = p.childNodes[i]; + const hashtagStuffedParagraphs = [...dom.querySelectorAll('p')].filter( + (p, index) => { + let hashtagCount = 0; + for (let i = 0; i < p.childNodes.length; i++) { + const node = p.childNodes[i]; - if (node.nodeType === Node.TEXT_NODE) { - const text = node.textContent.trim(); - if (text !== '') { - return false; - } - } else if (node.tagName === 'BR') { - // Ignore
- } else if (node.tagName === 'A') { - const linkText = node.textContent.trim(); - if (!linkText || !linkText.startsWith('#')) { - return false; + if (node.nodeType === Node.TEXT_NODE) { + const text = node.textContent.trim(); + if (text !== '') { + return false; + } + } else if (node.tagName === 'BR') { + // Ignore
+ } else if (node.tagName === 'A') { + const linkText = node.textContent.trim(); + if (!linkText || !linkText.startsWith('#')) { + return false; + } else { + hashtagCount++; + } } else { - hashtagCount++; + return false; } - } else { - return false; } - } - // Only consider "stuffing" if: - // - there are more than 3 hashtags - // - there are more than 1 hashtag in adjacent paragraphs - if (hashtagCount > 3) { - prevIndex = index; - return true; - } - if (hashtagCount > 1 && prevIndex && index === prevIndex + 1) { - prevIndex = index; - return true; - } - }); + // Only consider "stuffing" if: + // - there are more than 3 hashtags + // - there are more than 1 hashtag in adjacent paragraphs + if (hashtagCount > 3) { + prevIndex = index; + return true; + } + if (hashtagCount > 1 && prevIndex && index === prevIndex + 1) { + prevIndex = index; + return true; + } + }, + ); if (hashtagStuffedParagraphs?.length) { hashtagStuffedParagraphs.forEach((p) => { p.classList.add('hashtag-stuffing'); @@ -291,18 +289,20 @@ const defaultRejectFilterMap = Object.fromEntries( ); function extractTextNodes(dom, opts = {}) { const textNodes = []; + const rejectFilterMap = Object.assign( + {}, + defaultRejectFilterMap, + opts.rejectFilter?.reduce((acc, cur) => { + acc[cur] = true; + return acc; + }, {}), + ); const walk = document.createTreeWalker( dom, NodeFilter.SHOW_TEXT, { acceptNode(node) { - if (defaultRejectFilterMap[node.parentNode.nodeName]) { - return NodeFilter.FILTER_REJECT; - } - if ( - opts.rejectFilter && - opts.rejectFilter.includes(node.parentNode.nodeName) - ) { + if (rejectFilterMap[node.parentNode.nodeName]) { return NodeFilter.FILTER_REJECT; } return NodeFilter.FILTER_ACCEPT;