heywey
Member
- Aug 28, 2025
- 78
There have been a few threads in the suggestions subforum that can be done client-side, plus some other things that annoyed me about the site ui, so I made a little userscript to fix them. It can:
Also this should go without saying but running code that you don't understand from some random guy you don't know is generally a pretty bad idea. It's simple and tiny so it should be pretty easy to follow if you have any programming knowledge, but if you don't, idk, ask AI to walk you through it or something.
- hide those useless chat notification bubbles
- hide the word "suicide" in headers and page titles
- set maximum signature height
- prevent gifs in signatures from autoplaying
- automatically set dark/light mode based on browser/system preference
Also this should go without saying but running code that you don't understand from some random guy you don't know is generally a pretty bad idea. It's simple and tiny so it should be pretty easy to follow if you have any programming knowledge, but if you don't, idk, ask AI to walk you through it or something.
JavaScript:
// ==UserScript==
// @name sasu aio
// @namespace Violentmonkey Scripts
// @match https://sanctioned-suicide.net/*
// @grant none
// @version 3.1
// @author heywey
// @description
// ==/UserScript==
(function() {
'use strict';
//// SETTINGS
// privacy
const REPLACEMENT_WORD = "suicide"; // 'suicide' in headers (forum names, etc) gets replaced w this. just set to 'suicide' to disable
const REMOVE_SITE_NAME = false; // removes " | Sanctioned Suicide" from browser tab title
// signatures
const MAX_SIGNATURE_HEIGHT = 150; // max signature height in pixels (overflow gets a scrollbar)
const PREVENT_GIF_AUTOPLAY = true; // replaces gifs in signatures with black box until hovered with cursor
// visual tweaks
const MATCH_BROWSER_THEME = true; // automatically sets site theme to match browser preference (dark/light)
const HIDE_BADGE_INDICATOR = true; // hides chat notification bubble
//// UTIL
function injectCss(css) {
if (!css) return;
const style = document.createElement('style');
style.textContent = css;
document.head.appendChild(style);
}
function capitalize(str) {
return str.charAt(0).toUpperCase() + str.slice(1);
}
//// MODULES
function applyReplacementWord() {
if (REPLACEMENT_WORD.toLowerCase() === 'suicide') return;
const replacerLower = REPLACEMENT_WORD.toLowerCase();
const replacerTitle = capitalize(replacerLower);
// helper to replace text in nodes
function replaceTextInNode(node) {
// skip script, style, form elements
if (['SCRIPT', 'STYLE', 'TEXTAREA', 'INPUT'].includes(node.tagName)) return;
if (node.nodeType === Node.TEXT_NODE) {
const originalText = node.textContent;
const newText = originalText
.replace(/Suicide/g, replacerTitle)
.replace(/suicide/g, replacerLower);
if (newText !== originalText) {
node.textContent = newText;
}
return;
}
if (node.nodeType === Node.ELEMENT_NODE && !node.isContentEditable) {
for (let i = 0; i < node.childNodes.length; i++) {
replaceTextInNode(node.childNodes[i]);
}
}
}
// replace in headers
const headers = document.querySelectorAll('h1, h2, h3, h4, h5');
headers.forEach(header => replaceTextInNode(header));
// replace in title
let newTitle = document.title;
newTitle = newTitle
.replace(/Suicide/g, replacerTitle)
.replace(/suicide/g, replacerLower);
if (newTitle !== document.title) {
document.title = newTitle;
}
}
function applyRemoveSiteName() {
if (!REMOVE_SITE_NAME) return;
// removes " | Sanctioned Suicide" and any surrounding whitespace/pipes
const newTitle = document.title.replace(/[\s|]*Sanctioned Suicide/gi, '');
if (newTitle !== document.title) {
document.title = newTitle;
}
}
function applyMaxSignatureHeight() {
if (MAX_SIGNATURE_HEIGHT <= 0) return;
injectCss(`
.message-signature {
max-height: ${MAX_SIGNATURE_HEIGHT}px !important;
overflow-y: auto !important;
overflow-x: hidden !important;
}
`);
}
function applyPreventGifAutoplay() {
if (!PREVENT_GIF_AUTOPLAY) return;
// target images that look like gifs based on src, data-url, alt attributes
const gifSelectors = [
'.message-signature img[src*=".gif"]',
'.message-signature img[data-url*=".gif"]',
'.message-signature img[alt*=".gif"]'
].join(', ');
const hoverSelectors = gifSelectors.split(', ').map(s => s + ':hover').join(', ');
// set wrapper background to black and handle opacity
injectCss(`
.message-signature .bbImageWrapper {
background-color: #000 !important;
display: inline-block !important;
}
${gifSelectors} {
opacity: 0 !important;
}
/* show on hover */
${hoverSelectors} {
opacity: 1 !important;
}
`);
}
function applyMatchBrowserTheme() {
if (!MATCH_BROWSER_THEME) return;
// check if browser supports media queries and site object exists
if (window.matchMedia && typeof themehouse !== 'undefined' && themehouse.styleSwitch) {
const isOsDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
const targetMode = isOsDark ? 'dark' : 'light';
// attempt to detect current site mode to avoid redundant switches
let currentMode;
// check internal property if available
if (themehouse.styleSwitch.mode) {
currentMode = themehouse.styleSwitch.mode;
}
// fallback: check html classes/attributes
else {
const html = document.documentElement;
const isSiteDark = html.classList.contains('theme--dark') ||
html.classList.contains('uix_dark') ||
html.dataset.theme === 'dark';
currentMode = isSiteDark ? 'dark' : 'light';
}
// only switch if the modes don't match
if (currentMode !== targetMode) {
themehouse.styleSwitch.switchStyle(targetMode);
}
}
}
function applyHideBadgeIndicator() {
if (!HIDE_BADGE_INDICATOR) return;
injectCss(`
.badgeContainer::after {
content: none !important;
}
.badge {
display: none !important;
}
`);
}
//// INIT
function init() {
// privacy
applyRemoveSiteName();
applyReplacementWord();
// signatures
applyMaxSignatureHeight();
applyPreventGifAutoplay();
// visual tweaks
applyMatchBrowserTheme();
applyHideBadgeIndicator();
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
} else {
init();
}
})();
Last edited: