Reddit Bypass Enhancer

Bypass "open in app" prompts, unblur NSFW content & thumbnails, remove spoiler overlays.

  1. // ==UserScript==
  2. // @name Reddit Bypass Enhancer
  3. // @version 2.4
  4. // @description Bypass "open in app" prompts, unblur NSFW content & thumbnails, remove spoiler overlays.
  5. // @author UniverseDev
  6. // @license GPL-3.0-or-later
  7. // @match https://www.reddit.com/*
  8. // @match https://sh.reddit.com/*
  9. // @grant none
  10. // @run-at document-start
  11. // @noframes
  12. // @namespace https://greasyfork.org/en/users/1030895-universedev
  13. // ==/UserScript==
  14.  
  15. 'use strict';
  16.  
  17. (function () {
  18. function queryElementsDeep(selector) {
  19. const elements = new Set();
  20. try {
  21. document.querySelectorAll(selector).forEach(el => elements.add(el));
  22. document.querySelectorAll('*').forEach(el => {
  23. if (el.shadowRoot) {
  24. el.shadowRoot.querySelectorAll(selector).forEach(shadowEl => elements.add(shadowEl));
  25. }
  26. });
  27. } catch (error) {
  28. console.error("Error in queryElementsDeep:", error);
  29. }
  30. return [...elements];
  31. }
  32.  
  33. const SELECTORS = {
  34. nsfwModal: 'shreddit-async-loader[bundlename*="nsfw_blocking_modal"]',
  35. promptContainer: 'xpromo-nsfw-blocking-container > *',
  36. prompt: '.prompt',
  37. blurredContainer: 'shreddit-blurred-container',
  38. thumbnailBlur: '.thumbnail-blur',
  39. communityHighlightCard: 'community-highlight-card',
  40. thumbnailImage: 'img.mb-0.h-full.w-full.object-cover',
  41. thumbnailShadow: '.thumbnail-shadow',
  42. mediaBackground: '.bg-media-background',
  43. blurredSpan: 'span.inner.blurred',
  44. scrim: '.absolute.top-0.left-0.w-full.h-full.bg-scrim',
  45. imageFilter: 'img.mb-0.h-full.w-full.object-cover',
  46. video: 'shreddit-player, video',
  47. mediaTelemetryObserver: 'media-telemetry-observer',
  48. spoilerOverlay: '.absolute.inset-0.overflow-visible.flex.items-center.justify-center'
  49. };
  50.  
  51. function removeNSFWBlock() {
  52. try {
  53. document.querySelector(SELECTORS.nsfwModal)?.remove();
  54. document.querySelector(SELECTORS.promptContainer)?.shadowRoot?.querySelector(SELECTORS.prompt)?.remove();
  55.  
  56. document.getElementById("nsfw-qr-dialog")?.remove();
  57. document.querySelector("body > div:nth-child(7)")?.remove();
  58.  
  59. document.querySelectorAll('body > *').forEach(el => {
  60. if (el.style.backdropFilter) el.style.backdropFilter = 'none';
  61. });
  62.  
  63. document.querySelectorAll(SELECTORS.blurredContainer).forEach(container => {
  64. try {
  65. if (container.shadowRoot?.innerHTML && container.firstElementChild) {
  66. container.firstElementChild.addEventListener('click', e => {
  67. e.preventDefault();
  68. if (e.target.closest(SELECTORS.mediaTelemetryObserver)) {
  69. e.stopPropagation();
  70. }
  71. container.classList.add('clicked-container');
  72. e.target.click();
  73. }, { once: true });
  74.  
  75. container.firstElementChild.click();
  76. }
  77. } catch (error) {
  78. console.error("Error processing blurred container:", error, container);
  79. }
  80. });
  81.  
  82. document.querySelectorAll(SELECTORS.thumbnailBlur).forEach(el => el.classList.remove('thumbnail-blur'));
  83. document.querySelectorAll(SELECTORS.communityHighlightCard).forEach(card => card.removeAttribute('blurred'));
  84. document.querySelectorAll(SELECTORS.imageFilter).forEach(img => img.style.removeProperty('filter'));
  85. document.querySelectorAll(SELECTORS.video).forEach(video => video.classList.remove('blur'));
  86. document.querySelector(SELECTORS.thumbnailShadow)?.remove();
  87. document.querySelector(SELECTORS.mediaBackground)?.style.setProperty('background-color', 'transparent');
  88.  
  89. queryElementsDeep(SELECTORS.blurredSpan).forEach(span => span.style.removeProperty('filter'));
  90. queryElementsDeep(SELECTORS.scrim).forEach(scrim => scrim.remove());
  91. queryElementsDeep(SELECTORS.spoilerOverlay).forEach(spoiler => spoiler.remove());
  92.  
  93. document.querySelectorAll('div.thumbnail-shadow').forEach(div => {
  94. if (div.querySelector('svg[icon-name="nsfw-fill"]')) {
  95. div.remove();
  96. }
  97. });
  98.  
  99. } catch (error) {
  100. console.error("Error in removeNSFWBlock:", error);
  101. }
  102. }
  103.  
  104. const observer = new MutationObserver(mutations => {
  105. for (const mutation of mutations) {
  106. if (mutation.addedNodes.length) {
  107. removeNSFWBlock();
  108. break;
  109. }
  110. }
  111. });
  112.  
  113. observer.observe(document.documentElement, { childList: true, subtree: true });
  114.  
  115. const shredditCheckInterval = setInterval(() => {
  116. if (!document.querySelector('shreddit-app')) {
  117. observer.disconnect();
  118. clearInterval(shredditCheckInterval);
  119. }
  120. }, 5000);
  121. })();