Skip to content

Instantly share code, notes, and snippets.

@kadiwa4
Last active August 11, 2022 22:48
Show Gist options
  • Select an option

  • Save kadiwa4/709ee81fd1f681f64422cf7bafe7dec5 to your computer and use it in GitHub Desktop.

Select an option

Save kadiwa4/709ee81fd1f681f64422cf7bafe7dec5 to your computer and use it in GitHub Desktop.
may save you a few clicks
// ==UserScript==
// @name speedrun.com
// @namespace https://www.speedrun.com/
// @version 0.1.6
// @description may save you some time
// @match https://www.speedrun.com/*
// @icon https://www.speedrun.com/themeasset/68q1p7rp/1st
// @updateURL https://gist.github.com/KaDiWa4/709ee81fd1f681f64422cf7bafe7dec5/raw/speedrun.com.user.js
// @downloadURL https://gist.github.com/KaDiWa4/709ee81fd1f681f64422cf7bafe7dec5/raw/speedrun.com.user.js
// ==/UserScript==
(function src() {
"use strict";
function onAddedChild(parent, fn) {
const observer = new MutationObserver((records, observer) => {
for (let record of records) {
for (let node of record.addedNodes) {
fn(node, observer);
}
}
});
observer.observe(parent, { childList: true });
return observer;
}
function childLoaded(parent, pred = () => true) {
return new Promise((resolve) => {
let node = parent.children[0];
if (node !== undefined && pred(node)) {
resolve(node);
}
let resolved = false;
const observer = onAddedChild(parent, (node, observer) => {
if (!resolved && pred(node)) {
resolved = true;
observer.disconnect();
resolve(node);
}
});
// Check if the child has been loaded in the meantime.
node = parent.children[0];
if (node !== undefined && pred(node)) {
observer.disconnect();
resolve(node);
}
});
}
function srcUrlEscape(str) {
// This might not always work.
return str.replaceAll(" ", "_").replace(/\W/g, (char) => (char === "-") ? "-" : "");
}
// Delete this script (cargo.js) before it downloads more stuff.
// Same can maybe be done with sb.scorecardresearch.com, www.google-analytics.com
// and static.hotjar.com.
document.head.querySelector('script[src*="//cloud-strife.speedrun.com/"]')?.remove();
// Stripe is only needed for payment, but is always loaded.
if (!location.pathname.endsWith("/supporter/subscribe")) {
let stripeIFramesRemoved = 0;
onAddedChild(document.body, (node, observer) => {
if (node instanceof HTMLIFrameElement && node.src !== "" && new URL(node.src).hostname === "js.stripe.com") {
stripeIFramesRemoved++;
if (stripeIFramesRemoved >= 2) {
observer.disconnect();
}
node.remove();
}
});
}
function homePage() {
const latestTweets = document.getElementById("latest-tweets");
if (latestTweets === null) { return; }
latestTweets.parentNode.remove();
let twitterIFramesRemoved = 0;
onAddedChild(document.body, (node, observer) => {
if (node instanceof HTMLIFrameElement && node.title !== "" && node.title.startsWith("Twitter ")) {
twitterIFramesRemoved++;
if (twitterIFramesRemoved >= 2) {
observer.disconnect();
}
node.remove();
}
});
}
homePage();
function leaderboardPage() {
// Check that we're on a leaderboard page and have moderator rights.
if (document.getElementsByClassName("gamemenu-mod-tools").length === 0) { return; }
const leaderboarddiv = document.getElementById("leaderboarddiv");
function newPrimaryLeaderboard(table) {
for (let row of table.querySelectorAll("tbody > tr")) {
let url = row.getAttribute("data-target").match(/^\/\w+\/run\/\w+$/)[0];
url += "/edit";
const cell = document.createElement("td");
cell.className = "nobr center hidden-xs hidden-md-down";
const anchor = document.createElement("a");
anchor.href = url;
const image = document.createElement("i");
image.className = "fas fa-edit";
image.title = "Edit";
anchor.appendChild(image);
cell.appendChild(anchor);
row.appendChild(cell);
}
}
onAddedChild(leaderboarddiv, (node) => {
if (node.id === "primary-leaderboard") {
newPrimaryLeaderboard(node);
}
});
const table = leaderboarddiv.getElementById("primary-leaderboard");
if (table !== null) {
newPrimaryLeaderboard(table);
}
}
leaderboardPage();
async function modhubPage() {
const moderationPage = document.querySelector("main [component-name=ModerationPage]");
const sidebarLayout = (await childLoaded(moderationPage)).querySelector(".panel, :scope > .sidebar-layout");
const contentColumn = await childLoaded(sidebarLayout, (node) => node.className === "content-column");
const tickets = await childLoaded(contentColumn, (node) => node.previousSibling?.className === "panel");
function updateTicket(ticket) {
const viewAnchor = ticket.querySelector(".ticket-actions-container a");
let categoryDiv = ticket.querySelector(".ticket-label-container > :last-child > :first-child");
let url = viewAnchor.getAttribute("href").match(/^(\/\w+)\/run\//)[1];
if (categoryDiv.childNodes[0].data === "Level: ") {
const level = categoryDiv.getElementsByTagName("span")[0].textContent;
categoryDiv = categoryDiv.nextSibling;
url += `/level/${srcUrlEscape(level)}`;
}
const category = categoryDiv.getElementsByTagName("span")[0].textContent;
url += `#${srcUrlEscape(category)}`;
// Add the link to the page.
const title = ticket.getElementsByClassName("ticket-title")[0];
title.normalize();
const titleText = title.childNodes[0];
titleText.splitText(titleText.length - 4);
const anchor = document.createElement("a");
anchor.href = url;
anchor.target = "_blank";
anchor.textContent = titleText.data;
title.replaceChild(anchor, titleText);
}
onAddedChild(tickets, updateTicket);
for (let ticket of tickets.children) {
if (ticket.className === "ticket-container") {
updateTicket(ticket);
}
}
}
if (location.pathname === "/modhub") {
modhubPage();
}
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment