Loop Fix

Saving loop for current tab and fixes video repeating in playlist

  1. // ==UserScript==
  2. // @name Loop Fix
  3. // @description Saving loop for current tab and fixes video repeating in playlist
  4. // @version 0.1.19
  5. // @author 0vC4
  6. // @namespace https://greasyfork.org/users/670183
  7. // @match *://*.youtube.com/*
  8. // @icon https://www.google.com/s2/favicons?sz=64&domain=youtube.com
  9. // @run-at document-start
  10. // @license MIT
  11. // @grant none
  12. // ==/UserScript==
  13.  
  14. (() => {
  15. function blockEvents(condition, ...events) {
  16. events = events.flat();
  17. const tag = window.EventTarget.prototype;
  18. tag._add = tag.addEventListener;
  19. tag.addEventListener = function (name, callback, options) {
  20. if (!events.includes(name)) return tag._add.call(this, name, callback, options);
  21.  
  22. function cb(e) {
  23. if (!condition.call(this)) return;
  24. callback.call(this, e);
  25. };
  26.  
  27. tag._add.call(this, name, cb, options);
  28. };
  29. }
  30.  
  31. blockEvents(function() {
  32. return !this.loop; // have loop = block events
  33. }, 'pause', 'timeupdate', 'waiting');
  34. })();
  35.  
  36. window.loopState = JSON.parse(window.sessionStorage.getItem('loopState')) ?? false;
  37. function clicking(e) {
  38. window.loopState = JSON.parse(this.ariaChecked);
  39. window.sessionStorage.setItem('loopState', window.loopState);
  40. };
  41.  
  42. window.setInterval(()=>{
  43. if (!location.href.includes('watch') && !location.href.includes('shorts')) return;
  44. const vid = window.document.querySelector('video.html5-main-video');
  45. if (!vid) return;
  46. // apply loopState after .src or page refresh
  47. if (vid.loop != window.loopState) vid.loop = window.loopState;
  48. // attach loop click detector
  49. const repeat = window.document.querySelectorAll('.ytp-menuitem[tabindex="-1"]')[0];
  50. if (repeat && repeat.onclick != clicking) {
  51. repeat.onclick = clicking;
  52. }
  53. });