Redgifs Embed Tweaks

tweaks redgifs embed/iframe video

נכון ליום 21-11-2023. ראה הגרסה האחרונה.

  1. // ==UserScript==
  2. // @name Redgifs Embed Tweaks
  3. // @namespace https://greasyfork.org/pt-BR/users/821661
  4. // @match https://www.redgifs.com/ifr/*
  5. // @grant GM_registerMenuCommand
  6. // @grant GM_addStyle
  7. // @grant GM_setValue
  8. // @grant GM_getValue
  9. // @version 0.2.2
  10. // @author hdyzen
  11. // @description tweaks redgifs embed/iframe video
  12. // @license MIT
  13. // ==/UserScript==
  14.  
  15. (function () {
  16. 'use strict';
  17. // Autoplay state
  18. const autoplay = GM_getValue('autoplay', true);
  19. // Open state
  20. const openLink = GM_getValue('openlink', false);
  21. // Autopause state
  22. const autoPause = GM_getValue('autoPause', true);
  23. // Muted state
  24. const muted = GM_getValue('muted', false);
  25. // Bloat state
  26. const bloat = GM_getValue('bloat', false);
  27. // Title
  28. const title = 'Click for toggle';
  29. // Autoplay toggle
  30. function autoplayToggle() {
  31. GM_setValue('autoplay', !autoplay);
  32. location.reload();
  33. }
  34. // Open link when click on video
  35. function openLinkToggle() {
  36. GM_setValue('openlink', !openLink);
  37. location.reload();
  38. }
  39. // Pause when video less than 80% visible
  40. function pauseVideoToggle() {
  41. GM_setValue('autoPause', !autoPause);
  42. location.reload();
  43. }
  44. // Muted default
  45. function mutedToggle() {
  46. GM_setValue('muted', !muted);
  47. location.reload();
  48. }
  49. // Open link when click on video
  50. function bloatToggle() {
  51. GM_setValue('bloat', !bloat);
  52. location.reload();
  53. }
  54. // Prevent opening video link
  55. if (!openLink) {
  56. document.addEventListener('click', (e) => {
  57. if (!e.target.closest('.videoLink')) return;
  58. e.preventDefault();
  59. });
  60. }
  61. // Remove bloat
  62. if (bloat) GM_addStyle(`.userInfo,.logo,#shareButton{display:none!important}`);
  63. // Intersection observer video
  64. function observerVideo(target) {
  65. const observer = new IntersectionObserver(
  66. (entries) => {
  67. for (const entry of entries) {
  68. if (!entry.isIntersecting && !entry.target.paused) entry.target.pause();
  69. }
  70. },
  71. {
  72. threshold: 0.8,
  73. }
  74. );
  75. observer.observe(target);
  76. }
  77. // Menu commands
  78. (function menuCommands() {
  79. // Autoplay
  80. const commandAutoplay = GM_registerMenuCommand('Autoplay: ON', autoplayToggle, {
  81. title: title,
  82. });
  83. if (!autoplay) {
  84. GM_registerMenuCommand('Autoplay: OFF', autoplayToggle, {
  85. title: title,
  86. id: commandAutoplay,
  87. });
  88. }
  89. // Open link
  90. const commandLink = GM_registerMenuCommand('Open link when click: OFF', openLinkToggle, {
  91. title: title,
  92. });
  93. if (openLink) {
  94. GM_registerMenuCommand('Open link when click: ON', openLinkToggle, {
  95. title: title,
  96. id: commandLink,
  97. });
  98. }
  99. // Pause video
  100. const commandPause = GM_registerMenuCommand('Autopause: ON', pauseVideoToggle, {
  101. title: title,
  102. });
  103. if (!autoPause) {
  104. GM_registerMenuCommand('Autopause: OFF', pauseVideoToggle, {
  105. title: title,
  106. id: commandPause,
  107. });
  108. }
  109. // Muted
  110. const commandMuted = GM_registerMenuCommand('Muted: ON', mutedToggle, {
  111. title: title,
  112. });
  113. if (!muted) {
  114. GM_registerMenuCommand('Muted: OFF', mutedToggle, {
  115. title: title,
  116. id: commandMuted,
  117. });
  118. }
  119. // Bloat
  120. const commandBloat = GM_registerMenuCommand('Hide Bloat: OFF', bloatToggle, {
  121. title: title,
  122. });
  123. if (bloat) {
  124. GM_registerMenuCommand('Hide Bloat: ON', bloatToggle, {
  125. title: title,
  126. id: commandBloat,
  127. });
  128. }
  129. })();
  130. // Mutation observer for pause video
  131. const observer = new MutationObserver((mutations) => {
  132. mutations.forEach((mutation) => {
  133. if (mutation.type === 'childList' && mutation.target.classList.contains('routeWrapper')) {
  134. mutation.addedNodes.forEach((node) => {
  135. const video = node.querySelector('.videoLink video');
  136. if (video && !autoplay) {
  137. video.removeAttribute('autoplay');
  138. disconnectObserver();
  139. }
  140. if (video && autoPause) {
  141. observerVideo(video);
  142. disconnectObserver();
  143. }
  144. if (video && !muted) {
  145. const muteButton = document.querySelector('.soundOff');
  146. const click = new MouseEvent('click', {
  147. bubbles: true,
  148. cancelable: true,
  149. });
  150. muteButton.dispatchEvent(click);
  151. disconnectObserver();
  152. }
  153. });
  154. }
  155. });
  156. });
  157. // Disconnect observer when the mutations are processed
  158. function disconnectObserver() {
  159. const pendingMutations = observer.takeRecords();
  160. if (pendingMutations.length === 0) {
  161. observer.disconnect();
  162. }
  163. }
  164. observer.observe(document.body, {
  165. childList: true,
  166. subtree: true,
  167. });
  168. })();