aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/utils.mjs
diff options
context:
space:
mode:
authorHsieh Chin Fan <pham@topo.tw>2024-10-14 14:47:04 +0800
committerHsieh Chin Fan <pham@topo.tw>2024-10-14 16:57:34 +0800
commit5d4a43abb181ae4fd63d2365210ea4949f10012e (patch)
tree733f756c9a4bc635b9c56a33b374ff9ee7e99961 /src/utils.mjs
parent01b1b9e76cea73ddbe3cdf4bee524b61c182b14d (diff)
feat: improve GeoLink generation
* Stop searching pattern by linkify, Add links with geo URI scheme by async function instead * Search text nodes with patterns, and replace them with links * Add checker for valid degree/meter coordinated * Add query string "xy" anyway
Diffstat (limited to 'src/utils.mjs')
-rw-r--r--src/utils.mjs44
1 files changed, 44 insertions, 0 deletions
diff --git a/src/utils.mjs b/src/utils.mjs
index d408b3d..1fe3ce5 100644
--- a/src/utils.mjs
+++ b/src/utils.mjs
@@ -133,3 +133,47 @@ export const insideParent = (childElement, parentElement) => {
133 childRect.bottom > parentRect.top + offset 133 childRect.bottom > parentRect.top + offset
134 ) 134 )
135} 135}
136
137/**
138 * replaceTextNodes.
139 * @description Search current nodes by pattern, and replace them by new node
140 * @todo refactor to smaller methods
141 * @param {HTMLElement} element
142 * @param {RegExp} pattern
143 * @param {Function} newNode - Create new node by each result of String.prototype.matchAll
144 */
145export const replaceTextNodes = (
146 element,
147 pattern,
148 newNode = (match) => {
149 const link = document.createElement('a')
150 link.textContent(match.at(0))
151 return link
152 },
153) => {
154 const nodeIterator = document.createNodeIterator(
155 element,
156 window.NodeFilter.SHOW_TEXT,
157 node => node.textContent.match(pattern)
158 ? window.NodeFilter.FILTER_ACCEPT
159 : window.NodeFilter.FILTER_REJECT,
160 )
161
162 let node = nodeIterator.nextNode()
163 while (node) {
164 let index = 0
165 for (const match of node.textContent.matchAll(pattern)) {
166 const text = node.textContent.slice(index, match.index)
167 index = match.index + match.at(0).length
168 node.parentElement.insertBefore(document.createTextNode(text), node)
169 node.parentElement.insertBefore(newNode(match), node)
170 }
171 if (index < node.textContent.length) {
172 const text = node.textContent.slice(index)
173 node.parentElement.insertBefore(document.createTextNode(text), node)
174 }
175
176 node.parentElement.removeChild(node)
177 node = nodeIterator.nextNode()
178 }
179}