From afd8a5742bf64d3b5ee2df918cea2903810525e7 Mon Sep 17 00:00:00 2001 From: uwaa Date: Sat, 11 Jan 2025 06:38:49 +0000 Subject: [PATCH] make rot much faster and less errors --- rot.js | 114 ++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 69 insertions(+), 45 deletions(-) diff --git a/rot.js b/rot.js index 79896f4..b70fa6d 100644 --- a/rot.js +++ b/rot.js @@ -18,7 +18,10 @@ function waitUntil(selector) { return new Promise((resolve, reject) => { const el = document.querySelector(selector); - if (el) resolve(el); + if (el) { + resolve(el); + return; + } new MutationObserver((mutationRecords, observer) => { // Query for elements matching the specified selector Array.from(document.querySelectorAll(selector)).forEach((element) => { @@ -45,16 +48,17 @@ function setMusic(url) { if (audio.src == url || (!url && audio.src === window.location.toString())) return; - + audio.pause(); - // This line will cause a lot of errors. - // Setting src to "" will cause any pending .play()s to fail. - audio.src = ""; if (url) { console.log("Setting music: " + url); audio.src = url; playMusic(); + } else { + // This line will cause a lot of errors. + // Setting src to "" will cause any pending .play()s to fail. + audio.src = ""; } } @@ -82,25 +86,64 @@ document.getElementById("user-audio-percentage").innerHTML = Math.round(audio.volume * 100) + "%"; } + //Registers a mutation observer for an element. Upon triggering and the callback + //returning true, observation ceases. All observers are disconnected and the array is cleared. + const observers = []; + function waitUntilSpecial(selector) { + return new Promise((resolve, reject) => { + const newObserver = new MutationObserver((mutationRecords, observer) => { + // Query for elements matching the specified selector + Array.from(document.querySelectorAll(selector)).forEach((element) => { + //Callback + if (!resolve(element)) + return; + + //Clean up + for (const o of observers) + o.disconnect(); + observers.length = 0; + }); + }); + observers.push(newObserver); + newObserver.observe(document.documentElement, { + childList: true, + subtree: true + }); + }); + } + //Theme application function applyMainTheme() { console.log("Applying main theme"); setMusic(null); - setTimeout(() => { - let pageMusic = document.querySelector('meta[name="pageMusic"]')?.content || document.getElementById("pageMusic")?.getAttribute("href"); - setMusic(pageMusic); + + waitUntilSpecial('meta[name="pageMusic"]').then((pageMusic) => { + setMusic(pageMusic.content); playMusic(); - - let pageImage = document.querySelector('meta[name="pageImage"]')?.content || document.getElementById("pageImage")?.getAttribute("href"); - setImage(pageImage); - }, 500); + return true; + }); + + waitUntilSpecial("#pageMusic").then((pageMusic) => { + setMusic(pageMusic.getAttribute("href")); + playMusic(); + return true; + }); } function applyUserTheme() { console.log("Applying user theme"); setMusic(null); - setTimeout(() => { - let ptp = findProfileThemingPost(); + + waitUntilSpecial(".pin").then((pinnedPost) => { + if (pinnedPost.nextElementSibling + .querySelector(".StatusBody") + .querySelector(".text") + .innerHTML + .replace(/(<([^>]+)>)/ig, '') + .search(/profile theming post/ig) == -1) + return false; + + let ptp = pinnedPost.nextElementSibling.querySelector(".StatusBody"); if (ptp) { //Configured by post let musicContainer = ptp.querySelector(".audio-container") @@ -114,9 +157,13 @@ setImage(rand(imageContainer.getElementsByTagName("img")).src); else setImage(null); - return; + return true; + } else { + return false; } - + }, observers); + + waitUntilSpecial(".user-profile-field-name").then(() => { let fields = [...document.getElementsByClassName("user-profile-field-name")] if (fields.length != 0) { //Configured by fields @@ -131,34 +178,11 @@ setImage(rand(imageFields).nextElementSibling.title); else setImage(null); - return; + return true; + } else { + return false; } - }, 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 @@ -228,12 +252,12 @@ 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";