4chan Image Blur Toggle

Blurs images on 4chan. Catalog view - double click image to unblur and open the thread. Thread view - click image to unblur, click again to reapply blur.

  1. // ==UserScript==
  2. // @name 4chan Image Blur Toggle
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.0
  5. // @description Blurs images on 4chan. Catalog view - double click image to unblur and open the thread. Thread view - click image to unblur, click again to reapply blur.
  6. // @author Trojihn
  7. // @license MIT
  8. // @match *://boards.4chan.org/*
  9. // @grant none
  10. // @icon https://s.4cdn.org/image/favicon.ico
  11. // ==/UserScript==
  12.  
  13. (function() {
  14. 'use strict'; // Use strict mode to enforce cleaner JavaScript
  15.  
  16. // Function to apply blur and toggle on click for images
  17. function applyBlur(img) {
  18. img.style.filter = 'blur(15px)'; // Apply a 15px blur effect to the image
  19. img.style.transition = 'filter 0.2s'; // Add a transition for smooth unblurring
  20.  
  21. let isBlurred = true; // Track the blur state
  22.  
  23. // Add a click event listener to the image
  24. img.addEventListener('click', event => {
  25. event.preventDefault(); // Prevent the default action (navigating to the link) immediately
  26.  
  27. // Check if the image is currently blurred
  28. if (isBlurred) {
  29. img.style.filter = 'none'; // Unblur the image
  30. isBlurred = false; // Update the state to indicate the image is now unblurred
  31. } else {
  32. // If the image is unblurred and clicked again, check if we are in thread view
  33. const isThreadView = img.closest('.fileThumb'); // Check if the image is in thread view
  34. if (isThreadView) {
  35. img.style.filter = 'blur(15px)'; // Reapply the blur effect
  36. isBlurred = true; // Update the state to indicate the image is now blurred
  37. } else {
  38. // If in catalog view, allow navigation
  39. const link = img.closest('a'); // Find the closest anchor tag (link) around the image
  40. if (link) {
  41. window.location.href = link.href; // Navigate to the thread URL found in the link's href attribute
  42. }
  43. }
  44. }
  45. });
  46. }
  47.  
  48. // Function to apply blur to images in both thread and catalog views
  49. function blurAllImages() {
  50. // Select all images in thread view
  51. const threadImages = document.querySelectorAll('.fileThumb img');
  52. // Select all images in catalog view using the class "thumb"
  53. const catalogImages = document.querySelectorAll('.thumb');
  54.  
  55. // Apply the blur effect to all selected images
  56. [...threadImages, ...catalogImages].forEach(applyBlur);
  57. }
  58.  
  59. // Call the function to apply blur to images initially
  60. blurAllImages();
  61.  
  62. // Create a MutationObserver to watch for new images added to the page dynamically
  63. const observer = new MutationObserver(mutations => {
  64. // Iterate through each mutation (change) detected
  65. mutations.forEach(mutation => {
  66. // For each added node in the mutation
  67. mutation.addedNodes.forEach(node => {
  68. // Check if the added node is an element node and matches the image selectors
  69. if (
  70. node.nodeType === 1 && // Ensure it's an element node
  71. (node.matches('.fileThumb img') || node.matches('.thumb')) // Match either thread or catalog images
  72. ) {
  73. applyBlur(node); // Apply the blur effect to the new image
  74. }
  75. });
  76. });
  77. });
  78.  
  79. // Start observing the document body for changes in its child nodes
  80. observer.observe(document.body, { childList: true, subtree: true });
  81. })();