(hint: DetectorHint, success: () => void)
| 203 | let hintMatchObserver: MutationObserver; |
| 204 | |
| 205 | function detectUsingHint(hint: DetectorHint, success: () => void) { |
| 206 | stopDetectingUsingHint(); |
| 207 | |
| 208 | const matchSelector = (hint.match || []).join(', '); |
| 209 | |
| 210 | function checkMatch(target: Element) { |
| 211 | if (target.matches?.(matchSelector)) { |
| 212 | stopDetectingUsingHint(); |
| 213 | success(); |
| 214 | return true; |
| 215 | } |
| 216 | return false; |
| 217 | } |
| 218 | |
| 219 | function setupMatchObserver(target: Element) { |
| 220 | hintMatchObserver?.disconnect(); |
| 221 | if (checkMatch(target)) { |
| 222 | return; |
| 223 | } |
| 224 | hintMatchObserver = new MutationObserver(() => checkMatch(target)); |
| 225 | hintMatchObserver.observe(target, {attributes: true}); |
| 226 | } |
| 227 | |
| 228 | const target = document.querySelector(hint.target); |
| 229 | if (target) { |
| 230 | setupMatchObserver(target); |
| 231 | } else { |
| 232 | hintTargetObserver = new MutationObserver((mutations) => { |
| 233 | const handledTargets = new Set<Node>(); |
| 234 | for (const mutation of mutations) { |
| 235 | if (handledTargets.has(mutation.target)) { |
| 236 | continue; |
| 237 | } |
| 238 | handledTargets.add(mutation.target); |
| 239 | if (mutation.target instanceof Element) { |
| 240 | const target = mutation.target.querySelector(hint.target); |
| 241 | if (target) { |
| 242 | hintTargetObserver.disconnect(); |
| 243 | setupMatchObserver(target); |
| 244 | break; |
| 245 | } |
| 246 | } |
| 247 | } |
| 248 | }); |
| 249 | hintTargetObserver.observe(document.documentElement, {childList: true, subtree: true}); |
| 250 | } |
| 251 | } |
| 252 | |
| 253 | function stopDetectingUsingHint() { |
| 254 | hintTargetObserver?.disconnect(); |
no test coverage detected