Reddit Bypass Enchancer

Bypass the "open in app prompt", unblur NSFW content and thumbnails, remove the blur from community highlight cards, and add redditenhancer clicked container class.

目前為 2025-01-29 提交的版本,檢視 最新版本

  1. // ==UserScript==
  2. // @name Reddit Bypass Enchancer
  3. // @version 2.0
  4. // @description Bypass the "open in app prompt", unblur NSFW content and thumbnails, remove the blur from community highlight cards, and add redditenhancer clicked container class.
  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. 'use strict';
  15.  
  16. (function () {
  17. function queryElementsDeep(selector) {
  18. const foundElements = new Set();
  19. try {
  20. const lightDomElements = document.querySelectorAll(selector);
  21. lightDomElements.forEach(el => foundElements.add(el));
  22. const allElements = document.querySelectorAll('*');
  23. for (const el of allElements) {
  24. if (el.shadowRoot) {
  25. const shadowElements = el.shadowRoot.querySelectorAll(selector);
  26. shadowElements.forEach(el => foundElements.add(el));
  27. }
  28. }
  29. } catch (error) {
  30. console.error("Error in queryElementsDeep:", error);
  31. }
  32. return Array.from(foundElements);
  33. }
  34.  
  35. const SELECTORS = {
  36. nsfwModal: `${'shreddit-async-loader'}[${'bundlename'}*="nsfw_blocking_modal"]`,
  37. promptContainer: `${'xpromo-nsfw-blocking-container'} > *`,
  38. prompt: '.prompt',
  39. blurredContainer: 'shreddit-blurred-container',
  40. thumbnailBlur: '.thumbnail-blur',
  41. communityHighlightCard: 'community-highlight-card',
  42. thumbnailImage: 'img.mb-0.h-full.w-full.object-cover',
  43. thumbnailShadow: '.thumbnail-shadow',
  44. mediaBackground: '.bg-media-background',
  45. blurredSpan: 'span.inner.blurred',
  46. scrim: '.absolute.top-0.left-0.w-full.h-full.bg-scrim',
  47. imageFilter: 'img.mb-0.h-full.w-full.object-cover',
  48. video: 'shreddit-player, video',
  49. mediaTelemetryObserver: 'media-telemetry-observer',
  50. mediaPlayerLoader: 'shreddit-async-loader[bundlename="media_player_loader"]',
  51. shredditPlayer: 'shreddit-player',
  52. outerContainer: 'div.outer.h-full',
  53. badgeContainer: '.flex.items-center.gap-2xs.text-white',
  54. clickedContainerClass: 'redditenhancer-clicked-container'
  55. };
  56.  
  57. const BLURRED_TAG = SELECTORS.blurredContainer;
  58. const MEDIA_TELEMETRY_OBSERVER_SELECTOR = SELECTORS.mediaTelemetryObserver;
  59. const BADGE_CONTAINER = SELECTORS.badgeContainer;
  60. const CLICKED_CONTAINER_CLASS = SELECTORS.clickedContainerClass;
  61.  
  62.  
  63. function removeNSFWBlock() {
  64. try {
  65. const nsfwModal = document.querySelector(SELECTORS.nsfwModal);
  66. if (nsfwModal) {
  67. nsfwModal.remove();
  68. }
  69.  
  70. const promptContainer = document.querySelector(SELECTORS.promptContainer);
  71. let prompt = null;
  72. if (promptContainer && promptContainer.shadowRoot) {
  73. prompt = promptContainer.shadowRoot.querySelector(SELECTORS.prompt);
  74. }
  75. if (prompt) {
  76. prompt.remove();
  77. }
  78.  
  79. const blurredContainers = document.querySelectorAll(BLURRED_TAG);
  80. blurredContainers.forEach(container => {
  81. try {
  82. if (container.shadowRoot?.innerHTML && container.firstElementChild) {
  83. container.firstElementChild.addEventListener('click', function(e) {
  84. e.preventDefault();
  85. if (e.target.closest(MEDIA_TELEMETRY_OBSERVER_SELECTOR)) {
  86. e.stopPropagation();
  87. }
  88.  
  89. container.classList.add(CLICKED_CONTAINER_CLASS);
  90.  
  91. e.target.click();
  92. }, { once: true });
  93. container.firstElementChild.click();
  94. }
  95. } catch (error) {
  96. console.error("Error processing blurred container:", error, container);
  97. }
  98. });
  99.  
  100. document.querySelectorAll(SELECTORS.thumbnailBlur).forEach(el => el.classList.remove('thumbnail-blur'));
  101. document.querySelectorAll(SELECTORS.communityHighlightCard).forEach(card => card.removeAttribute('blurred'));
  102.  
  103. document.querySelectorAll(SELECTORS.imageFilter).forEach(img => img.style.removeProperty('filter'));
  104. document.querySelectorAll(SELECTORS.video).forEach(video => {
  105. video.classList.remove('blur');
  106. });
  107.  
  108. const thumbnailShadow = document.querySelector(SELECTORS.thumbnailShadow);
  109. if (thumbnailShadow) {
  110. thumbnailShadow.remove();
  111. }
  112.  
  113. const mediaBackground = document.querySelector(SELECTORS.mediaBackground);
  114. if (mediaBackground) {
  115. mediaBackground.style.backgroundColor = 'transparent';
  116. }
  117.  
  118. queryElementsDeep(SELECTORS.blurredSpan).forEach(span => {
  119. span.style.removeProperty('filter');
  120. });
  121. queryElementsDeep(SELECTORS.scrim).forEach(scrim => {
  122. scrim.remove();
  123. });
  124. queryElementsDeep(BADGE_CONTAINER).forEach(badge => {
  125. badge.remove();
  126. });
  127. }
  128. catch (error) {
  129. console.error("Error in removeNSFWBlock:", error);
  130. }
  131. }
  132.  
  133. const observer = new MutationObserver(removeNSFWBlock);
  134. const contentContainer = document.documentElement;
  135. observer.observe(contentContainer, {
  136. childList: true,
  137. subtree: true,
  138. attributes: false
  139. });
  140.  
  141. const shredditCheckInterval = setInterval(() => {
  142. if (!document.querySelector('shreddit-app')) {
  143. observer.disconnect();
  144. clearInterval(shredditCheckInterval);
  145. }
  146. }, 5000);
  147. })();