mirror of
https://git.pleroma.social/sjw/pleroma-fe.git
synced 2024-12-23 00:53:45 +01:00
167 lines
4.8 KiB
JavaScript
Executable File
167 lines
4.8 KiB
JavaScript
Executable File
function PleromaModLoader () {
|
|
this.config = {
|
|
"modDirectory": "/instance/pleroma-mods/",
|
|
"mods": []
|
|
};
|
|
this.loadConfig();
|
|
this.loadedMods = {};
|
|
this.classes = {};
|
|
}
|
|
[
|
|
function loadMods () {
|
|
for (const mod of this.config.mods) {
|
|
const modObject = new PleromaMod(mod);
|
|
modObject.include();
|
|
this.loadedMods[mod] = modObject;
|
|
}
|
|
},
|
|
|
|
function loadConfig () {
|
|
window.fetch("/instance/pleroma-mod-config.json").then((response) => {
|
|
if (response.ok) {
|
|
response.json().then((json) => {
|
|
for (const key in json) {
|
|
this.config[key] = json[key];
|
|
}
|
|
this.loadMods();
|
|
}).catch((error) => {
|
|
console.error("can't parse loader config");
|
|
console.error(error);
|
|
});
|
|
}
|
|
}).catch((error) => {
|
|
console.warn("can't load mod loader config");
|
|
console.warn(error);
|
|
});
|
|
},
|
|
|
|
function registerClass (className, object) {
|
|
this.classes[className] = object;
|
|
},
|
|
|
|
function waitUntilReady () {
|
|
const postPanel = document.getElementsByClassName("post-status-form");
|
|
const loginPanel = document.getElementsByClassName("login-form");
|
|
if (postPanel.length > 0 || loginPanel.length > 0) {
|
|
for (var modName in this.loadedMods) {
|
|
const mod = this.loadedMods[modName];
|
|
if (mod.instance.onReady) {
|
|
mod.instance.onReady();
|
|
}
|
|
}
|
|
this.createObserver();
|
|
} else {
|
|
window.setTimeout(() => { this.waitUntilReady(); }, 1000);
|
|
}
|
|
},
|
|
|
|
function createObserver () {
|
|
this.containers = {
|
|
main: document.getElementsByClassName("main")[0],
|
|
notifications: document.getElementsByClassName("notifications")[0]
|
|
};
|
|
|
|
const observerConfig = { subtree: true, childList: true };
|
|
this.observer = new MutationObserver((mutations, observer) => {
|
|
for (var modName in this.loadedMods) {
|
|
const mod = this.loadedMods[modName];
|
|
if (mod.instance.onMutation) {
|
|
for (const mutation of mutations) {
|
|
let filter = null;
|
|
if (mod.instance.config.filter) {
|
|
filter = new RegExp(mod.instance.config.filter.join("|"));
|
|
}
|
|
if (!filter || filter.test(mutation.target.className)) {
|
|
mod.instance.onMutation(mutation, observer);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
});
|
|
this.observer.observe(this.containers.main, observerConfig);
|
|
if (this.containers.notifications) {
|
|
this.observer.observe(this.containers.notifications, observerConfig);
|
|
}
|
|
}
|
|
].forEach((fn) => { PleromaModLoader.prototype[fn.name] = fn; });
|
|
[
|
|
function registerMod (mod) {
|
|
window.__pleromaModLoader.registerClass(mod.name, mod);
|
|
},
|
|
|
|
function includeModScript (src) {
|
|
return PleromaModLoader.includeScript(window.__pleromaModLoader.config.modDirectory + src);
|
|
},
|
|
|
|
function includeModCss (src) {
|
|
return PleromaModLoader.includeCss(window.__pleromaModLoader.config.modDirectory + src);
|
|
},
|
|
|
|
function includeScript (src) {
|
|
return new Promise((resolve) => {
|
|
const body = document.getElementsByTagName("body")[0];
|
|
const script = document.createElement("script");
|
|
script.setAttribute("src", src);
|
|
script.setAttribute("type", "text/javascript");
|
|
script.onload = () => { resolve(); };
|
|
body.appendChild(script);
|
|
});
|
|
},
|
|
|
|
function includeCss (src) {
|
|
return new Promise((resolve) => {
|
|
const head = document.getElementsByTagName("head")[0];
|
|
const link = document.createElement("link");
|
|
link.setAttribute("href", src);
|
|
link.setAttribute("rel", "stylesheet");
|
|
link.setAttribute("type", "text/css");
|
|
link.onload = () => { resolve(); };
|
|
head.appendChild(link);
|
|
});
|
|
},
|
|
|
|
function getModDir () {
|
|
return window.__pleromaModLoader.config.modDirectory;
|
|
}
|
|
].forEach((fn) => { PleromaModLoader[fn.name] = fn; });
|
|
|
|
function PleromaMod (name) {
|
|
this.name = name;
|
|
this.instance = null;
|
|
}
|
|
[
|
|
function getClassName () {
|
|
let className = "PleromaMod";
|
|
const nameParts = this.name.split("-");
|
|
for (const namePart of nameParts) {
|
|
className += namePart.substring(0, 1).toUpperCase();
|
|
className += namePart.substring(1);
|
|
}
|
|
return className;
|
|
},
|
|
|
|
function include () {
|
|
console.log("loading " + this.name);
|
|
PleromaModLoader.includeScript(
|
|
PleromaModLoader.getModDir() + "pleroma-mod-" + this.name + "/mod.js"
|
|
).then(() => {
|
|
this.modLoaded();
|
|
});
|
|
},
|
|
|
|
function modLoaded () {
|
|
console.log(this.name + " loaded");
|
|
this.instance = new window.__pleromaModLoader.classes[this.getClassName()]();
|
|
this.run();
|
|
},
|
|
|
|
function run () {
|
|
if (this.instance) {
|
|
this.instance.run();
|
|
}
|
|
}
|
|
].forEach((fn) => { PleromaMod.prototype[fn.name] = fn; });
|
|
|
|
window.__pleromaModLoader = new PleromaModLoader();
|
|
window.__pleromaModLoader.waitUntilReady();
|