fixes and optimizations
This commit is contained in:
parent
350e88221f
commit
b79a921932
1 changed files with 186 additions and 191 deletions
377
rot.js
377
rot.js
|
@ -2,220 +2,194 @@
|
||||||
// one rotten apple spoils the bunch
|
// one rotten apple spoils the bunch
|
||||||
|
|
||||||
(() => {
|
(() => {
|
||||||
let oldPushState = history.pushState;
|
function getPromiseFromEvent(item, event) {
|
||||||
history.pushState = function pushState() {
|
return new Promise((resolve) => {
|
||||||
let ret = oldPushState.apply(this, arguments);
|
const listener = () => {
|
||||||
window.dispatchEvent(new Event('pushstate'));
|
item.removeEventListener(event, listener);
|
||||||
window.dispatchEvent(new Event('locationchange'));
|
resolve();
|
||||||
return ret;
|
}
|
||||||
};
|
item.addEventListener(event, listener);
|
||||||
|
|
||||||
let oldReplaceState = history.replaceState;
|
|
||||||
history.replaceState = function replaceState() {
|
|
||||||
let ret = oldReplaceState.apply(this, arguments);
|
|
||||||
window.dispatchEvent(new Event('replacestate'));
|
|
||||||
window.dispatchEvent(new Event('locationchange'));
|
|
||||||
return ret;
|
|
||||||
};
|
|
||||||
|
|
||||||
window.addEventListener('popstate', () => {
|
|
||||||
window.dispatchEvent(new Event('locationchange'));
|
|
||||||
});
|
|
||||||
})();
|
|
||||||
|
|
||||||
function getPromiseFromEvent(item, event) {
|
|
||||||
return new Promise((resolve) => {
|
|
||||||
const listener = () => {
|
|
||||||
item.removeEventListener(event, listener);
|
|
||||||
resolve();
|
|
||||||
}
|
|
||||||
item.addEventListener(event, listener);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// MIT Licensed
|
|
||||||
// Author: jwilson8767
|
|
||||||
function waitUntil(selector) {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
const el = document.querySelector(selector);
|
|
||||||
if (el) resolve(el);
|
|
||||||
new MutationObserver((mutationRecords, observer) => {
|
|
||||||
// Query for elements matching the specified selector
|
|
||||||
Array.from(document.querySelectorAll(selector)).forEach((element) => {
|
|
||||||
resolve(element);
|
|
||||||
//Once we have resolved we don't need the observer anymore.
|
|
||||||
observer.disconnect();
|
|
||||||
});
|
|
||||||
}).observe(document.documentElement, {
|
|
||||||
childList: true,
|
|
||||||
subtree: true
|
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
}
|
|
||||||
|
// MIT Licensed
|
||||||
|
// Author: jwilson8767
|
||||||
|
function waitUntil(selector) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const el = document.querySelector(selector);
|
||||||
|
if (el) resolve(el);
|
||||||
|
new MutationObserver((mutationRecords, observer) => {
|
||||||
|
// Query for elements matching the specified selector
|
||||||
|
Array.from(document.querySelectorAll(selector)).forEach((element) => {
|
||||||
|
resolve(element);
|
||||||
|
//Once we have resolved we don't need the observer anymore.
|
||||||
|
observer.disconnect();
|
||||||
|
});
|
||||||
|
}).observe(document.documentElement, {
|
||||||
|
childList: true,
|
||||||
|
subtree: true
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function sex(sex) {
|
function sex(sex) {
|
||||||
return sex // Sex
|
return sex // Sex
|
||||||
}
|
}
|
||||||
|
|
||||||
function rand(list) {
|
function rand(list) {
|
||||||
return list ? list[list.length * Math.random() | 0] : null;
|
return list ? list[list.length * Math.random() | 0] : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rot music player
|
// Rot music player
|
||||||
const audio = document.createElement("audio");
|
const audio = document.createElement("audio");
|
||||||
audio.loop = true;
|
audio.loop = true;
|
||||||
audio.id = "user-music";
|
audio.id = "user-music";
|
||||||
audio.style = "display:none;";
|
audio.style = "display:none;";
|
||||||
localStorage.audiovolume = (audio.volume = localStorage.audiovolume ? localStorage.audiovolume / 100 : 0.5) * 100;
|
localStorage.audiovolume = (audio.volume = localStorage.audiovolume ? localStorage.audiovolume / 100 : 0.5) * 100;
|
||||||
|
|
||||||
function setMusic(url) {
|
function setMusic(url) {
|
||||||
if (audio.src == url || (!url && audio.src === ""))
|
if (audio.src == url || (!url && audio.src === window.location.toString()))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!audio.paused || audio.src != "") {
|
|
||||||
console.log("Stopping music");
|
|
||||||
audio.pause();
|
audio.pause();
|
||||||
// This line will cause a lot of errors.
|
// This line will cause a lot of errors.
|
||||||
// Setting src to "" will cause any pending .play()s to fail.
|
// Setting src to "" will cause any pending .play()s to fail.
|
||||||
audio.src = "";
|
audio.src = "";
|
||||||
|
|
||||||
|
if (url) {
|
||||||
|
console.log("Setting music: " + url);
|
||||||
|
audio.src = url;
|
||||||
|
playMusic();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (url) {
|
function playMusic() {
|
||||||
console.log("Setting music: " + url);
|
//Starts playing the music if it isn't muted and isn't already playing
|
||||||
audio.src = url;
|
if (audio.src && audio.src != "" && audio.paused && !audio.muted)
|
||||||
playMusic();
|
audio.play().catch(() => getPromiseFromEvent(window, 'click').then(audio.play));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
function playMusic() {
|
function setImage(url) {
|
||||||
//Starts playing the music if it isn't muted and isn't already playing
|
if (url) {
|
||||||
if (audio.src && audio.src != "" && audio.paused && !audio.muted)
|
console.log("Setting background: " + url);
|
||||||
audio.play().catch(() => getPromiseFromEvent(window, 'click').then(audio.play));
|
document.getElementById("app-loaded").style.setProperty("--body-background-image", "url(" + url + ")");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function setImage(url) {
|
//Audio control events
|
||||||
if (!url)
|
function volumeSet(number) {
|
||||||
url = '/static/background.jpg';
|
localStorage.audiovolume = Math.round((audio.volume = number) * 100);
|
||||||
|
updateVolumeLabel();
|
||||||
|
}
|
||||||
|
function volumeAdd(number) {
|
||||||
|
volumeSet(Math.min(1, Math.max(0, audio.volume + number)));
|
||||||
|
}
|
||||||
|
function updateVolumeLabel() {
|
||||||
|
document.getElementById("user-audio-percentage").innerHTML = Math.round(audio.volume * 100) + "%";
|
||||||
|
}
|
||||||
|
|
||||||
console.log("Setting background: " + url);
|
//Initialize audio controls
|
||||||
document.getElementById("app-loaded").style.setProperty("--body-background-image", "url(" + url + ")");
|
waitUntil("#music-controls").then((controls) => {
|
||||||
}
|
updateVolumeLabel();
|
||||||
|
controls.querySelector("#music-up").onclick = () => volumeAdd(0.05);
|
||||||
//Audio control events
|
controls.querySelector("#music-down").onclick = () => volumeAdd(-0.05);
|
||||||
function volumeSet(number) {
|
|
||||||
localStorage.audiovolume = Math.round((audio.volume = number) * 100);
|
|
||||||
updateVolumeLabel();
|
|
||||||
}
|
|
||||||
function volumeAdd(number) {
|
|
||||||
volumeSet(Math.min(1, Math.max(0, audio.volume + number)));
|
|
||||||
}
|
|
||||||
function updateVolumeLabel() {
|
|
||||||
document.getElementById("user-audio-percentage").innerHTML = Math.round(audio.volume * 100) + "%";
|
|
||||||
}
|
|
||||||
|
|
||||||
//Initialize audio controls
|
|
||||||
waitUntil("#music-controls").then((controls) => {
|
|
||||||
updateVolumeLabel();
|
|
||||||
controls.querySelector("#music-up").onclick = () => volumeAdd(0.05);
|
|
||||||
controls.querySelector("#music-down").onclick = () => volumeAdd(-0.05);
|
|
||||||
})
|
|
||||||
|
|
||||||
waitUntil("#music-slider").then((slider) => {
|
|
||||||
updateVolumeLabel();
|
|
||||||
slider.oninput = () => volumeSet(slider.value / 100);
|
|
||||||
})
|
|
||||||
|
|
||||||
waitUntil("#music-mute").then((box) => {
|
|
||||||
audio.muted = box.checked = localStorage.audiomuted === "true";
|
|
||||||
box.addEventListener('click', () => {
|
|
||||||
localStorage.audiomuted = audio.muted = box.checked;
|
|
||||||
playMusic();
|
|
||||||
})
|
})
|
||||||
});
|
|
||||||
|
|
||||||
//Theme application
|
waitUntil("#music-slider").then((slider) => {
|
||||||
function applyMainTheme() {
|
updateVolumeLabel();
|
||||||
console.log("Applying main theme");
|
slider.oninput = () => volumeSet(slider.value / 100);
|
||||||
setTimeout(() => {
|
})
|
||||||
let pageMusic = document.querySelector('meta[name="pageMusic"]')?.content || document.getElementById("pageMusic")?.getAttribute("href");
|
|
||||||
setMusic(pageMusic);
|
|
||||||
playMusic();
|
|
||||||
|
|
||||||
let pageImage = document.querySelector('meta[name="pageImage"]')?.content || document.getElementById("pageImage")?.getAttribute("href");
|
waitUntil("#music-mute").then((box) => {
|
||||||
setImage(pageImage);
|
audio.muted = box.checked = localStorage.audiomuted === "true";
|
||||||
}, 1000);
|
box.addEventListener('click', () => {
|
||||||
}
|
localStorage.audiomuted = audio.muted = box.checked;
|
||||||
|
playMusic();
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
function applyUserTheme() {
|
//Theme application
|
||||||
console.log("Applying user theme");
|
function applyMainTheme() {
|
||||||
setMusic(null);
|
console.log("Applying main theme");
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
let ptp = findProfileThemingPost();
|
let pageMusic = document.querySelector('meta[name="pageMusic"]')?.content || document.getElementById("pageMusic")?.getAttribute("href");
|
||||||
if (ptp) {
|
setMusic(pageMusic);
|
||||||
//Configured by post
|
playMusic();
|
||||||
let musicContainer = ptp.querySelector(".audio-container")
|
|
||||||
if (musicContainer)
|
|
||||||
setMusic(rand(musicContainer.children).src);
|
|
||||||
else
|
|
||||||
setMusic(null);
|
|
||||||
|
|
||||||
let imageContainer = ptp.querySelector(".image-container")
|
let pageImage = document.querySelector('meta[name="pageImage"]')?.content || document.getElementById("pageImage")?.getAttribute("href");
|
||||||
if (imageContainer)
|
setImage(pageImage);
|
||||||
setImage(rand(imageContainer.getElementsByTagName("img")).src);
|
}, 1000);
|
||||||
else
|
|
||||||
setImage(null);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let fields = [...document.getElementsByClassName("user-profile-field-name")]
|
|
||||||
if (fields.length != 0) {
|
|
||||||
//Configured by fields
|
|
||||||
let musicFields = fields.filter((x) => x.title.toLowerCase().replace(/\s+/g, '') == "music")
|
|
||||||
if (musicFields.length > 0)
|
|
||||||
setMusic(rand(musicFields).nextElementSibling.title);
|
|
||||||
else
|
|
||||||
setMusic(null);
|
|
||||||
|
|
||||||
let imageFields = fields.filter((x) => x.title.toLowerCase().replace(/\s+/g, '') == "image")
|
|
||||||
if (imageFields.length > 0)
|
|
||||||
setImage(rand(imageFields).nextElementSibling.title);
|
|
||||||
else
|
|
||||||
setImage(null);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}, 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
function findProfileThemingPost() {
|
|
||||||
try {
|
|
||||||
let pinnedPosts = document.getElementsByClassName("pin");
|
|
||||||
if (pinnedPosts.length == 0)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
let ptp = [...pinnedPosts].find( // I hate this. It keeps getting worse.
|
|
||||||
(x) => x.nextElementSibling
|
|
||||||
.querySelector(".StatusBody")
|
|
||||||
.querySelector(".text")
|
|
||||||
.innerHTML
|
|
||||||
.replace(/(<([^>]+)>)/ig, '')
|
|
||||||
.search(/profile theming post/ig) != -1
|
|
||||||
)
|
|
||||||
if (!ptp)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
return ptp.nextElementSibling.querySelector(".StatusBody");
|
|
||||||
} catch (e) {
|
|
||||||
//Future-proofing
|
|
||||||
console.error(e);
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
//Switch-based monkey patching router bullshit
|
function applyUserTheme() {
|
||||||
{
|
console.log("Applying user theme");
|
||||||
let lastPath = window.location.pathname;
|
setMusic(null);
|
||||||
addEventListener('locationchange', (event) => {
|
setTimeout(() => {
|
||||||
|
let ptp = findProfileThemingPost();
|
||||||
|
if (ptp) {
|
||||||
|
//Configured by post
|
||||||
|
let musicContainer = ptp.querySelector(".audio-container")
|
||||||
|
if (musicContainer)
|
||||||
|
setMusic(rand(musicContainer.children).src);
|
||||||
|
else
|
||||||
|
setMusic(null);
|
||||||
|
|
||||||
|
let imageContainer = ptp.querySelector(".image-container")
|
||||||
|
if (imageContainer)
|
||||||
|
setImage(rand(imageContainer.getElementsByTagName("img")).src);
|
||||||
|
else
|
||||||
|
setImage(null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let fields = [...document.getElementsByClassName("user-profile-field-name")]
|
||||||
|
if (fields.length != 0) {
|
||||||
|
//Configured by fields
|
||||||
|
let musicFields = fields.filter((x) => x.title.toLowerCase().replace(/\s+/g, '') == "music")
|
||||||
|
if (musicFields.length > 0)
|
||||||
|
setMusic(rand(musicFields).nextElementSibling.title);
|
||||||
|
else
|
||||||
|
setMusic(null);
|
||||||
|
|
||||||
|
let imageFields = fields.filter((x) => x.title.toLowerCase().replace(/\s+/g, '') == "image")
|
||||||
|
if (imageFields.length > 0)
|
||||||
|
setImage(rand(imageFields).nextElementSibling.title);
|
||||||
|
else
|
||||||
|
setImage(null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
function findProfileThemingPost() {
|
||||||
|
try {
|
||||||
|
let pinnedPosts = document.getElementsByClassName("pin");
|
||||||
|
if (pinnedPosts.length == 0)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
let ptp = [...pinnedPosts].find( // I hate this. It keeps getting worse.
|
||||||
|
(x) => x.nextElementSibling
|
||||||
|
.querySelector(".StatusBody")
|
||||||
|
.querySelector(".text")
|
||||||
|
.innerHTML
|
||||||
|
.replace(/(<([^>]+)>)/ig, '')
|
||||||
|
.search(/profile theming post/ig) != -1
|
||||||
|
)
|
||||||
|
if (!ptp)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return ptp.nextElementSibling.querySelector(".StatusBody");
|
||||||
|
} catch (e) {
|
||||||
|
//Future-proofing
|
||||||
|
console.error(e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Switch-based monkey patching router bullshit
|
||||||
|
let lastPath = null;
|
||||||
|
function updateRot() {
|
||||||
let newPath = window.location.pathname;
|
let newPath = window.location.pathname;
|
||||||
if (lastPath == newPath)
|
if (lastPath == newPath)
|
||||||
return;
|
return;
|
||||||
|
@ -266,7 +240,28 @@ function findProfileThemingPost() {
|
||||||
applyMainTheme();
|
applyMainTheme();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Monkey patches
|
||||||
|
addEventListener('locationchange', updateRot);
|
||||||
|
|
||||||
|
const oldPushState = history.pushState;
|
||||||
|
history.pushState = function pushState() {
|
||||||
|
const ret = oldPushState.apply(this, arguments);
|
||||||
|
updateRot();
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
|
||||||
|
const oldReplaceState = history.replaceState;
|
||||||
|
history.replaceState = function replaceState() {
|
||||||
|
const ret = oldReplaceState.apply(this, arguments);
|
||||||
|
updateRot();
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
|
||||||
|
window.addEventListener('popstate', () => {
|
||||||
|
updateRot();
|
||||||
});
|
});
|
||||||
}
|
})();
|
||||||
|
|
||||||
console.log("rot.js loaded");
|
console.log("rot.js loaded");
|
Loading…
Reference in a new issue