Greasy Fork is available in English.
Core library to handle webpages dom with userscripts from document-start
当前为
此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.greasyfork.icu/scripts/476017/1255617/userscripts-core-library.js
// ==UserScript==
// @name userscripts-core-library
// @version 0.1.0
// @author lucianjp
// @description Core library to handle webpages dom with userscripts from document-start
// ==/UserScript==
const core = {
ready: (callback) =>
document.readyState !== "loading"
? callback()
: document.addEventListener("DOMContentLoaded", callback),
addStyle: (aCss) => {
let head = document.getElementsByTagName("head")[0];
if (!head) {
console.error("Head element not found. Cannot add style.");
return null;
}
let style = document.createElement("style");
style.setAttribute("type", "text/css");
style.textContent = aCss;
head.appendChild(style);
return style;
},
observe: (observableCollection, continuous = false) => {
const observables = Array.from(observableCollection.entries()).filter(
([_, observable]) => !observable.currentValue
);
const observer = new MutationObserver(function (mutations) {
for (var i = mutations.length - 1; i >= 0; i--) {
const mutation = mutations[i];
const addedNodesLength = mutation.addedNodes.length;
if (addedNodesLength > 0) {
for (var j = addedNodesLength - 1; j >= 0; j--) {
const $node = mutation.addedNodes[j];
if ($node && $node.nodeType === 1) {
let observablesLength = observables.length;
for (let k = observablesLength - 1; k >= 0; k--) {
const [_, observable] = observables[k];
if (observable.test($node)) {
observable.set($node);
const last = observables.pop();
if (k < observablesLength - 1) observables[k] = last;
observablesLength = observablesLength - 1;
break;
}
}
}
}
if (observables.length === 0 && !continuous) {
observer.disconnect();
return;
}
}
}
});
observer.observe(document, { childList: true, subtree: true });
if (!continuous) core.ready(() => observer.disconnect());
return observer;
},
};
class Observable {
constructor(lookup, test) {
this.value = undefined;
this.callbacks = [];
this.lookup = lookup;
this.test = test;
if (typeof lookup === "function") {
this.value = lookup();
}
}
set(newValue) {
this.value = newValue;
this.executeCallbacks(this.value);
}
then(callback) {
if (typeof callback === "function") {
this.callbacks.push(callback);
if (this.value) callback(this.value);
}
return this;
}
executeCallbacks(value) {
this.callbacks.forEach((callback) => callback(value));
}
get currentValue() {
return this.value;
}
}
class ObservableCollection extends Map {
constructor() {
super();
}
add(name, observable) {
this.set(name, observable);
return observable;
}
}