From e774e551b50af7dfa320adb5e9b5cc7f790f0e52 Mon Sep 17 00:00:00 2001 From: Hsieh Chin Fan Date: Mon, 21 Oct 2024 20:50:14 +0800 Subject: refactor: use MuationObserver to update contents BREAKING CHANGE: * generateMaps no more called when content changes --- src/utils.mjs | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) (limited to 'src/utils.mjs') diff --git a/src/utils.mjs b/src/utils.mjs index 327bee4..9149ac2 100644 --- a/src/utils.mjs +++ b/src/utils.mjs @@ -5,7 +5,7 @@ * @param {Function} callback */ export const onRemove = (element, callback) => { - const parent = element.parentNode + const parent = element.parentElement if (!parent) throw new Error('The node must already be attached') const obs = new window.MutationObserver(mutations => { @@ -138,35 +138,40 @@ export const insideParent = (childElement, parentElement) => { * replaceTextNodes. * @description Search current nodes by pattern, and replace them by new node * @todo refactor to smaller methods - * @param {HTMLElement} element + * @param {HTMLElement} rootNode * @param {RegExp} pattern * @param {Function} newNode - Create new node by each result of String.prototype.matchAll */ export const replaceTextNodes = ( - element, + rootNode, pattern, - newNode = (match) => { + addNewNode = (match) => { const link = document.createElement('a') link.textContent(match.at(0)) return link }, ) => { const nodeIterator = document.createNodeIterator( - element, + rootNode, window.NodeFilter.SHOW_TEXT, - node => node.textContent.match(pattern) + node => node.textContent.match(pattern) && !node.parentElement.closest('code') ? window.NodeFilter.FILTER_ACCEPT : window.NodeFilter.FILTER_REJECT, ) let node = nodeIterator.nextNode() + const nodeArray = [] while (node) { let index = 0 for (const match of node.textContent.matchAll(pattern)) { const text = node.textContent.slice(index, match.index) + const newNode = addNewNode(match) + if (!newNode) continue + index = match.index + match.at(0).length node.parentElement.insertBefore(document.createTextNode(text), node) - node.parentElement.insertBefore(newNode(match), node) + node.parentElement.insertBefore(newNode, node) + nodeArray.push(newNode) } if (index < node.textContent.length) { const text = node.textContent.slice(index) @@ -176,6 +181,8 @@ export const replaceTextNodes = ( node.parentElement.removeChild(node) node = nodeIterator.nextNode() } + + return nodeArray } /** -- cgit v1.2.3-70-g09d2