// ==UserScript== // @name blocked catbox soundpost fix // @namespace fuwamocobaubau // @description Replaces files.catbox.moe links with files.pixstash.moe on soundposts. files.pixstash.moe is a simple proxy to bypass ISP blocks. // @author fuwamocobaubau // @license MIT // @version 0.1 // @match *://boards.4chan.org/* // @match *://boards.4channel.org/* // @match *://desuarchive.org/* // @match *://arch.b4k.co/* // @match *://archived.moe/* // @match *://warosu.org/* // @match *://archive.nyafuu.org/* // @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== // @grant none // @downloadURL none // ==/UserScript== (function() { 'use strict'; window.isChanX = document.documentElement && document.documentElement.classList.contains('fourchan-x'); function rewriteCatbox(target) { let posts = target.classList.contains('post') ? [ target ] : target.querySelectorAll('.post'); let filename = null; let filenameLocations = { '.fileText .file-info .fnfull': 'textContent', '.fileText .file-info > a': 'textContent', '.fileText > a': 'title', '.fileText': 'textContent' } posts.forEach(post => { Object.keys(filenameLocations).some(function (selector) { const node = post.querySelector(selector); node && (filename = node[filenameLocations[selector]]); if (filename && filename.includes('files.catbox.moe')) { node[filenameLocations[selector]] = filename.replace('files.catbox.moe', 'files.pixstash.moe') } }); }); } async function doInit() { rewriteCatbox(document.body); const observer = new MutationObserver(function (mutations) { mutations.forEach(function (mutation) { if (mutation.type === 'childList') { mutation.addedNodes.forEach(function (node) { if (node.nodeType === Node.ELEMENT_NODE) { rewriteCatbox(node); } }); } }); }); observer.observe(document.body, { childList: true, subtree: true }); } document.addEventListener('4chanXInitFinished', doInit); // The timeout makes sure 4chan X will have added it's classes and be identified. setTimeout(function () { // If it's already known 4chan X is installed this can be skipped. if (!isChanX) { if (document.readyState !== 'loading') { doInit(); } else { document.addEventListener('DOMContentLoaded', doInit); } } }, 0); })();