Guest User

Untitled

a guest
Jun 4th, 2025
64
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // ==UserScript==
  2. // @name         Toggle Post Filters (Images / No Quote Backlinks / Grayscale / Blur)
  3. // @namespace    http://tampermonkey.net/
  4. // @version      2.3
  5. // @description  Toggle to hide posts without images, or posts with images but containing quotelinks in backlinks. Also grayscale and/or blur images.
  6. // @match        https://boards.4chan.org/*
  7. // @icon         https://www.google.com/s2/favicons?sz=64&domain=4chan.org
  8. // @grant        none
  9. // ==/UserScript==
  10.  
  11. (function () {
  12.     'use strict';
  13.  
  14.     const hiddenClass = 'tm-hidden';
  15.  
  16.     const style = document.createElement('style');
  17.     style.textContent = `
  18.         .tm-hidden {
  19.             display: none !important;
  20.         }
  21.         .tm-toggle-button {
  22.             position: fixed;
  23.             right: 10px;
  24.             padding: 8px 12px;
  25.             margin-top: 5px;
  26.             background-color: #007BFF;
  27.             color: #fff;
  28.             border: none;
  29.             border-radius: 4px;
  30.             cursor: pointer;
  31.             z-index: 10000;
  32.             font-size: 14px;
  33.         }
  34.         .tm-toggle-button:hover {
  35.             background-color: #0056b3;
  36.         }
  37.     `;
  38.     document.head.appendChild(style);
  39.  
  40.     let filterNoImage = false;
  41.     let filterImageWithQuote = false;
  42.     let grayscaleEnabled = false;
  43.     let blurEnabled = false;
  44.  
  45.     function applyImageFilters() {
  46.         const images = document.querySelectorAll('.postContainer img');
  47.         images.forEach(img => {
  48.             let filters = [];
  49.             if (grayscaleEnabled) filters.push('grayscale(100%)');
  50.             if (blurEnabled) filters.push('blur(4px)');
  51.             img.style.filter = filters.join(' ');
  52.         });
  53.     }
  54.  
  55.     function updatePosts() {
  56.         const posts = document.querySelectorAll('.postContainer');
  57.         posts.forEach(post => {
  58.             const hasImage = post.querySelector('img') !== null;
  59.             const backlinkContainer = post.querySelector('.postInfo > .backlink');
  60.             const hasBacklinkQuote = backlinkContainer && backlinkContainer.querySelector('a.quotelink') !== null;
  61.  
  62.             let hide = false;
  63.             if (filterNoImage && !hasImage) hide = true;
  64.             if (filterImageWithQuote && hasImage && hasBacklinkQuote) hide = true;
  65.  
  66.             post.classList.toggle(hiddenClass, hide);
  67.         });
  68.  
  69.         applyImageFilters();
  70.     }
  71.  
  72.     function createButton(id, text, topOffset, onClick) {
  73.         const btn = document.createElement('button');
  74.         btn.id = id;
  75.         btn.className = 'tm-toggle-button';
  76.         btn.style.top = `${topOffset}px`;
  77.         btn.textContent = text;
  78.         btn.addEventListener('click', onClick);
  79.         document.body.appendChild(btn);
  80.         return btn;
  81.     }
  82.  
  83.     const btnImage = createButton('toggleImageBtn', 'Filter: Only Images [OFF]', 10, () => {
  84.         filterNoImage = !filterNoImage;
  85.         btnImage.textContent = `Filter: Only Images [${filterNoImage ? 'ON' : 'OFF'}]`;
  86.         updatePosts();
  87.     });
  88.  
  89.     const btnQuote = createButton('toggleQuoteBtn', 'Filter: Images w/ Backlink [OFF]', 50, () => {
  90.         filterImageWithQuote = !filterImageWithQuote;
  91.         btnQuote.textContent = `Filter: Images w/ Backlink [${filterImageWithQuote ? 'ON' : 'OFF'}]`;
  92.         updatePosts();
  93.     });
  94.  
  95.     const btnGray = createButton('toggleGrayBtn', 'Grayscale Images [OFF]', 90, () => {
  96.         grayscaleEnabled = !grayscaleEnabled;
  97.         btnGray.textContent = `Grayscale Images [${grayscaleEnabled ? 'ON' : 'OFF'}]`;
  98.         applyImageFilters();
  99.     });
  100.  
  101.     const btnBlur = createButton('toggleBlurBtn', 'Blur Images [OFF]', 130, () => {
  102.         blurEnabled = !blurEnabled;
  103.         btnBlur.textContent = `Blur Images [${blurEnabled ? 'ON' : 'OFF'}]`;
  104.         applyImageFilters();
  105.     });
  106.  
  107.     window.addEventListener('load', updatePosts);
  108.  
  109.     const observer = new MutationObserver(mutations => {
  110.         mutations.forEach(mutation => {
  111.             mutation.addedNodes.forEach(node => {
  112.                 if (node.nodeType === Node.ELEMENT_NODE) {
  113.                     const posts = node.matches('.postContainer') ? [node] : node.querySelectorAll('.postContainer');
  114.                     posts.forEach(post => {
  115.                         const hasImage = post.querySelector('img') !== null;
  116.                         const backlinkContainer = post.querySelector('.postInfo > .backlink');
  117.                         const hasBacklinkQuote = backlinkContainer && backlinkContainer.querySelector('a.quotelink') !== null;
  118.  
  119.                         let hide = false;
  120.                         if (filterNoImage && !hasImage) hide = true;
  121.                         if (filterImageWithQuote && hasImage && hasBacklinkQuote) hide = true;
  122.  
  123.                         post.classList.toggle(hiddenClass, hide);
  124.                     });
  125.                 }
  126.             });
  127.         });
  128.  
  129.         applyImageFilters(); // Also re-apply filters to any new images
  130.     });
  131.  
  132.     observer.observe(document.body, { childList: true, subtree: true });
  133. })();
  134.  
Advertisement
Add Comment
Please, Sign In to add comment