🏠 Home 

Youtube loop state keeper

To Loop or not To Loop is Yes

// ==UserScript==
// @name         Youtube loop state keeper
// @namespace    https//mmis1000.me/
// @version      0.1
// @description  To Loop or not To Loop is Yes
// @author       mmis1000
// @match        https://www.youtube.com/watch?*
// @grant        none
// ==/UserScript==
(function() {
'use strict';
const NS = "mmis1000";
let loopState = sessionStorage.getItem(NS + '_loopState');
let videoElement = document.querySelectorAll('video')[0];
if (loopState) {
setTimeout(function () {
try {
let oldState = JSON.parse(loopState);
if (oldState.loop) {
try {
// force the menu to populate
// as youtube only populate the menu after you do a right click
var e = videoElement.ownerDocument.createEvent('MouseEvents');
e.initMouseEvent('contextmenu', true, true,
videoElement.ownerDocument.defaultView, 1, 0, 0, 0, 0, false,
false, false, false,2, null);
videoElement.dispatchEvent(e);
videoElement.click()
let loopButton = Array.prototype.slice.call(document.querySelectorAll('.ytp-menuitem'), 0).filter((el)=>el.textContent.indexOf('循環播放') >= 0)[0];
loopButton.click()
console.log('restoring loop state...')
} catch (e) {
videoElement.loop = oldState.loop;
console.log('restoring loop state... (fallback to set video element loop attr)')
}
}
} catch(e) {}
let prevState = videoElement.loop;
videoElement.addEventListener("timeupdate", function () {
if (prevState !== videoElement.loop) {
console.log('updating loop state...')
prevState = videoElement.loop;
sessionStorage.setItem(NS + '_loopState', JSON.stringify({loop: videoElement.loop}));
}
})
}, 0);
}
})();