Save the setting permanently
// ==UserScript== // @name YouTube Perferred Settings for Private Mode // @namespace http://tampermonkey.net/ // @version 0.3 // @description Save the setting permanently // @author CY Fung // @icon data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='189' height='140' viewBox='0 0 270 200' %3E%3Crect x='0' y='0' width='270' height='200'%3E%3C/rect%3E%3Cpath d='m106 190c-27.3-.6-48.3-1.5-60.6-3-7.2-.9-9.9-1.5-13.2-2.7-8.1-2.4-15-8.7-18.9-16.2-2.7-5.7-4.5-15.3-5.7-30.6-2.4-26.4-2.4-49.2 0-75.9 1.2-13.8 3-23.1 5.4-28.5 3.9-7.8 11.1-14.4 19.2-16.8 9.6-3 32.7-4.8 76.2-5.7 35.4-.6 81.3.3 105.9 2.4 20.4 1.5 27.6 3.9 34.8 11.1 7.5 7.5 9.9 15 12 37.2 1.2 12.9 1.5 22.5 1.5 39 0 25.8-1.5 46.5-4.5 59.7-1.5 6.9-4.2 12-9 16.5-7.2 7.5-14.1 9.6-34.8 11.4-24.6 1.8-71.7 3-108.3 2.1z' fill='%23018000'/%3E%3Cpath d='M110 66 178 104 110 142Z' fill='%23fff'/%3E%3C/svg%3E // @license MIT // @match https://www.youtube.com/* // @require https://cdnjs.cloudflare.com/ajax/libs/js-cookie/3.0.1/js.cookie.min.js // @noframes // @grant GM_registerMenuCommand // @grant GM_unregisterMenuCommand // @grant GM.setValue // @grant GM.getValue // @grant GM_addStyle // @run-at document-start // ==/UserScript== (function () { 'use strict'; const gmKey = 'yps-r'; const cookieDomain ='youtube.com'; const STORE_VERSION = 1.1; /* this.j = g.N("ALT_PREF_COOKIE_NAME", "PREF"); this.u = g.N("ALT_PREF_COOKIE_DOMAIN", "youtube.com"); */ /*global Cookies*/ console.assert(typeof Cookies === "object"); const skipKeys = ['SIDCC','CONSISTENCY']; const isPassiveArgSupport = (typeof IntersectionObserver === 'function'); // https://caniuse.com/?search=observer // https://caniuse.com/?search=addEventListener%20passive const bubblePassive = isPassiveArgSupport ? { capture: false, passive: true } : false; const capturePassive = isPassiveArgSupport ? { capture: true, passive: true } : true; let registerH = 0; let navigationCheckPromiseResolve = null; const navigationCheckPromise = new Promise(r=>{ navigationCheckPromiseResolve=r; }); let _beginCookie = null; function regBegin(){ if(registerH>0){ GM_unregisterMenuCommand(registerH); } registerH = GM_registerMenuCommand("Setting Record Begin", begin, "b"); } function regEnd(){ if(registerH>0){ GM_unregisterMenuCommand(registerH); } registerH = GM_registerMenuCommand("Setting Record End", end, "e"); } function begin() { _beginCookie = Cookies.get(); regEnd(); let elm = document.querySelector('ytd-app'); if(elm) elm.classList.add('yps-recording'); } function end() { regBegin(); const beginCookie = _beginCookie; if (!beginCookie) return alert('Recording was not started.') _beginCookie = null; let elm = document.querySelector('ytd-app'); if(elm) elm.classList.remove('yps-recording'); let endCookie = Cookies.get(); let removed = []; let added = []; let keysBegin = Object.keys(beginCookie) let keysEnd = Object.keys(endCookie) let changed = []; for (const key of keysBegin) { if (keysEnd.includes(key)) { if (beginCookie[key] !== endCookie[key] && !skipKeys.includes(key)) { changed.push({ key: key, preValue: beginCookie[key], newValue: endCookie[key], changed: true }) } endCookie[key] = null; continue; } removed.push({ key: key, prevValue: beginCookie[key], removed: true }) } for (const key of keysEnd) { if (endCookie[key] === null) continue; added.push({ key: key, newValue: endCookie[key], added: true }) } if (removed.length > 0 || added.length > 0 || changed.length > 0) { let ret = prompt( [ `The recorded changes are as follows:`, `Removed keys: ${JSON.stringify(removed, null, 2)},`, `Added keys: ${JSON.stringify(added, null, 2)},`, `Changed keys: ${JSON.stringify(changed, null, 2)},`, `If you want to save these changes permanently, please type 'confirm'.` ].join('\n') , "confirm"); async function goSave(req){ let gmValue = null; try{ gmValue = await GM.getValue(gmKey); }catch(e){} if(!gmValue || typeof gmValue !=='string'){ gmValue = '{}'; } let pObj = null; try{ pObj = JSON.parse(gmValue) }catch(e){ } if(!pObj || pObj.version !== STORE_VERSION){ pObj = { version: STORE_VERSION, cookies:{ } }; } const cookies = pObj.cookies; for(const {key} of req.removed){ cookies[key]={ v: null } } for(const {key, newValue} of req.added){ cookies[key]={ v: newValue } } for(const {key, newValue} of req.changed){ cookies[key]={ v: newValue } } let success = true; try{ let gmValue = JSON.stringify(pObj); await GM.setValue(gmKey, gmValue); }catch(e){ console.warn(e); success = false; } if(success){ alert('The settings have been saved.') } } if(ret.toLowerCase()==='confirm'){ goSave({ version: STORE_VERSION, removed: removed, added: added, changed: changed }) } } else { alert('No changes can be recorded.') } } regBegin(); async function init(){ let _cookie = document.cookie||'' if(_cookie.indexOf('CONSISTENCY')>=0) return; if(_cookie.indexOf('SIDCC')>=0) return; let gmValue = null; try{ gmValue = await GM.getValue(gmKey); }catch(e){} if(!gmValue) return; let pObj = null; try{ pObj = JSON.parse(gmValue) }catch(e){ } if(!pObj || pObj.version !== STORE_VERSION){ pObj = { version: STORE_VERSION, cookies:{ } }; return; } if(!pObj.cookies) return; await Promise.resolve(0); const cookies = pObj.cookies; for (const key in cookies) { if(cookies[key].v===null){ Cookies.remove(key); }else if(typeof cookies[key].v ==='string'){ Cookies.set(key, cookies[key].v, { domain: cookieDomain} ) } } if(typeof navigationCheckPromiseResolve === 'function'){ navigationCheckPromiseResolve(); } } init(); async function updateRecord(){ return; let gmValue = null; try{ gmValue = await GM.getValue(gmKey); }catch(e){} if(!gmValue) return; let pObj = null; try{ pObj = JSON.parse(gmValue) }catch(e){ } if(!pObj || pObj.version !== STORE_VERSION){ pObj = { version: STORE_VERSION, cookies:{ } }; return; } if(!pObj.cookies) return; await Promise.resolve(0); const cookies = pObj.cookies; let overrided = 0; for (const key in cookies) { if(cookies[key].v===null){ if(typeof Cookies.get(key) ==='string'){ delete cookies[key]; overrided++; } }else if(typeof cookies[key].v ==='string'){ if(Cookies.get(key)!==cookies[key].v){ delete cookies[key]; overrided++; } } } if(overrided>0){ let success = true; try{ let gmValue = JSON.stringify(pObj); await GM.setValue(gmKey, gmValue); }catch(e){ console.warn(e); success = false; } if(success){ console.log('The perferred settings have been overrided.') } } } document.addEventListener('yt-navigate-finish', function(){ navigationCheckPromise.then(()=>{ // updateRecord(); }) }, bubblePassive) let keyupDT = 0; document.addEventListener('keyup', function(evt){ if(evt.shiftKey && evt.code ==='KeyR'){ }else{ if(keyupDT>0 && evt.code ==='KeyR'){ }else{ keyupDT = 0; return; } } let t = Date.now(); if(keyupDT>0){ if(t - keyupDT <300){ console.log('Shift-R-R') if(!_beginCookie){ begin(); }else{ end(); } } keyupDT = 0; } keyupDT = t; }, bubblePassive); GM_addStyle( `ytd-app.yps-recording{ filter:brightness(0.7); }` ); // Your code here... })();