// ==UserScript== // @name Youtube: Hide Recommended Videos // @namespace https://github.com/Zren // @version 1 // @description Hide recommended videos section // @icon https://youtube.com/favicon.ico // @author Zren // @include http*://*.youtube.com/* // @include http*://youtube.com/* // @include http*://*.youtu.be/* // @include http*://youtu.be/* // @run-at document-start // @downloadURL none // ==/UserScript== //--- Utils function observe(selector, config, callback) { var observer = new MutationObserver(function(mutations) { mutations.forEach(function(mutation){ callback(mutation); }); }); var target = document.querySelector(selector); console.log('target', target) observer.observe(target, config); return observer; } var documentLoaded = false; function tickUntilLoad(callback) { function tick() { console.log('tickUntilLoad tick'); callback(); if (!documentLoaded) { window.requestAnimationFrame(tick); } } callback(); window.requestAnimationFrame(tick); } function watchBodyForChanged(callback) { callback(); observe('body', { attributes: true, }, function(mutation) { console.log(mutation.type, mutation) if (mutation.attributeName === 'class') { callback(); } }); } //--- function getParent(e, selector) { var e2 = e.parentNode; while (e2) { if (e2.matches(selector)) { return e2; } e2 = e2.parentNode; } return null; } function hideRecommended() { console.log('hideRecommended'); var a = document.querySelector('.shelf-title-row a[href="/feed/recommended"]') if (a) { var section = getParent(a, '.item-section'); section.style.display = 'none'; console.log('hideRecommended HIDDEN'); } } tickUntilLoad(hideRecommended); document.addEventListener('DOMContentLoaded', function(){ documentLoaded = true; hideRecommended(); watchBodyForChanged(hideRecommended); });