Be smart!
This script should not be not be installed directly. It is a library for other scripts to include with the meta directive // @require https://updategf.qytechs.cn/scripts/454354/1114068/yssWaitForNode.js
// ==UserScript==
// @name yssWaitForNode
// @namespace https://ysslang.com/
// @version 1.1.1
// @description Be smart!
// @author ysslang
// @match *://*/*
// @note https://greasyfork.org/scripts/454354
// @grant none
// ==/UserScript==
class WaitForNode {
#currentURL;
#observerList = [];
#waitList = [];
constructor() { this.#currentURL = window.location.href; }
#checkIfUrlMatch(matcher) {
if (matcher === undefined || matcher === null) return false;
if (typeof matcher === "string") return new RegExp(matcher.trim()).test(this.#currentURL);
if (matcher instanceof RegExp) return matcher.test(this.#currentURL);
return false;
}
#determineParentElement(arg) {
if (typeof arg === "string") return document.querySelector(arg) || document.body;
else if (arg instanceof Element) return arg;
else return document.body;
}
#mergeOptions(options) {
options = options || {};
return {
immediate: [options.immediate, options.imdt].find((e) => e) || true,
recursive: [options.recursive, options.rcs].find((e) => e) || false,
once: [options.once].find((e) => e) || false,
subtree: [options.subtree, options.sbt].find((e) => e) || true,
childList: [options.childList, options.cld].find((e) => e) || true,
parentEl: this.#determineParentElement(options.parent),
};
}
#extractMatchedElements(mutations, selector, recursive) {
const matchedElements = [];
for (const { addedNodes } of mutations) {
for (const node of addedNodes) {
if (!node.tagName) continue;
else if (node.matches(selector)) matchedElements.push(node);
else if (recursive && node.firstElementChild) matchedElements.push(...node.querySelectorAll(selector));
} }
return matchedElements;
}
add(name, url, selector, callback, options) {
var urls = Array.isArray(url) ? url : [url];
if (!urls.some(this.#checkIfUrlMatch, this)) return;
this.on(selector, callback, this.#mergeOptions(options));
}
on(selector, callback, options) {
if (options.immediate) {
[...options.parentEl.querySelectorAll(selector)].forEach(callback);
}
const observer = new MutationObserver((mutations) => {
var elements = this.#extractMatchedElements(mutations, selector, options.recursive);
elements.forEach(callback);
if (elements && options.once) this.disconnect();
});
observer.observe(options.parentEl, { subtree: options.subtree, childList: options.childList, });
this.#observerList.push(observer);
}
stopAll() {
while (this.#observerList.length) this.#observerList.pop().disconnect();
}
}
var WFN = new WaitForNode();