Greasy Fork is available in English.
Automatically expands the "Show more" button in YouTube's subscription sidebar, keeping your subscriptions list fully expanded.
// ==UserScript== // @name YouTube - Auto Expand Subscriptions // @namespace http://tampermonkey.net/ // @version 0.3 // @description Automatically expands the "Show more" button in YouTube's subscription sidebar, keeping your subscriptions list fully expanded. // @author sharmanhall // @match https://www.youtube.com/* // @grant none // @run-at document-idle // @icon https://www.google.com/s2/favicons?sz=64&domain=youtube.com // @license MIT // @copyright 2024, sharmanhall // @supportURL https://github.com/sharmanhall/youtube-auto-expand/issues // @homepageURL https://github.com/sharmanhall/youtube-auto-expand // ==/UserScript== (function() { 'use strict'; const DEBUG = true; function log(...args) { if (DEBUG) console.log('[YT-Auto-Expand]', ...args); } function findShowMoreButton() { log('Starting button search...'); // Try various selectors const buttonSelectors = [ 'ytd-guide-collapsible-entry-renderer ytd-guide-entry-renderer#expander-item', '#items ytd-guide-collapsible-entry-renderer #expander-item', '#items ytd-guide-section-renderer ytd-guide-collapsible-entry-renderer' ]; for (const selector of buttonSelectors) { const element = document.querySelector(selector); if (element) { const endpoint = element.querySelector('a#endpoint'); if (endpoint) { const paperItem = endpoint.querySelector('tp-yt-paper-item'); if (paperItem && element.textContent.trim().includes('Show more')) { log('Found Show more button'); return endpoint; } } } } return null; } function expandSubscriptions() { const button = findShowMoreButton(); if (button) { log('Clicking button...'); button.click(); return true; } return false; } // Function to handle retries with delay function attemptExpansionWithRetry(retriesLeft = 10) { if (retriesLeft <= 0) { log('Max retries reached'); return; } if (!expandSubscriptions()) { setTimeout(() => { attemptExpansionWithRetry(retriesLeft - 1); }, 1000); } } // Wait specifically for the guide section to be ready function waitForGuide() { log('Setting up guide observer'); // First try to find the guide container const guideContainer = document.querySelector('tp-yt-app-drawer'); if (!guideContainer) { // If no container yet, watch for it const bodyObserver = new MutationObserver((mutations, obs) => { const container = document.querySelector('tp-yt-app-drawer'); if (container) { obs.disconnect(); observeGuide(container); } }); bodyObserver.observe(document.body, { childList: true, subtree: true }); } else { observeGuide(guideContainer); } } function observeGuide(container) { log('Guide container found, watching for changes'); // Only watch the guide container for changes const observer = new MutationObserver((mutations) => { // Only proceed if we see the section renderer if (document.querySelector('ytd-guide-section-renderer')) { // Check if button exists and isn't already clicked const button = findShowMoreButton(); if (button && button.textContent.includes('Show more')) { attemptExpansionWithRetry(); } } }); observer.observe(container, { childList: true, subtree: true, attributes: false, // Don't watch for attribute changes characterData: false // Don't watch for text changes }); // Make initial attempt attemptExpansionWithRetry(); } // Start observing as soon as possible waitForGuide(); // Also try when the window loads window.addEventListener('load', () => { log('Window loaded, making attempt...'); attemptExpansionWithRetry(); }); })();