정이용

// @name         YouTube Sidebar Always Expanded (Updated - No Video or Search Pages)
// @namespace    http://tampermonkey.net/
// @version      0.5
// @description  Attempts to keep the YouTube sidebar expanded, excluding video watch pages and search results pages.
// @author       Your Name
// @match        https://www.youtube.com/*
// @grant        none
// @run-at       document-idle
// ==/UserScript==

(function() {
    'use strict';

    // Function to expand the sidebar
    function expandSidebar() {
        // IMPORTANT: Always check if the current page is a video watch page or a search results page.
        // This prevents the script from trying to expand the sidebar in unwanted contexts.
        const isExcludedPage = window.location.pathname.startsWith('/watch') ||
                               window.location.pathname.startsWith('/results');

        if (isExcludedPage) {
            console.log('YouTube Sidebar: expandSidebar called on an excluded page (video or search results). Skipping expansion.');
            return; // Do nothing if on an excluded page
        }

        // Find the main application element which often controls sidebar visibility state
        const ytdApp = document.querySelector('ytd-app');
        // Find the guide button (hamburger menu icon) which toggles the sidebar
        // This selector is generally stable for the guide button.
        const guideButton = document.querySelector('yt-icon-button#guide-button');

        if (!ytdApp) {
            console.log('YouTube Sidebar: ytd-app element not found.');
            return;
        }

        if (!guideButton) {
            console.log('YouTube Sidebar: Guide button (#guide-button) not found.');
            return;
        }

        // Check the current state of the sidebar.
        // YouTube often uses the 'guide-persistent-and-visible' attribute on ytd-app
        // when the full sidebar is open.
        const isSidebarExpanded = ytdApp.hasAttribute('guide-persistent-and-visible');

        // If the sidebar is not expanded, click the guide button to expand it.
        if (!isSidebarExpanded) {
            // Check if the button is visible and clickable
            if (guideButton.offsetParent !== null) { // offsetParent checks if element is in the document and visible
                guideButton.click();
                console.log('YouTube Sidebar: Clicked guide button to expand sidebar.');
            } else {
                console.log('YouTube Sidebar: Guide button found but not visible/clickable.');
            }
        } else {
            console.log('YouTube Sidebar: Sidebar is already expanded.');
        }
    }

    // Use a MutationObserver to watch for changes in the DOM.
    // This is crucial because YouTube's UI loads dynamically, changes on navigation,
    // and can be modified by user actions or other scripts.
    const observer = new MutationObserver(mutations => {
        mutations.forEach(mutation => {
            // We are interested in attribute changes on 'ytd-app' which indicate layout changes.
            if (mutation.type === 'attributes' && mutation.target.tagName === 'YTD-APP') {
                console.log('YouTube Sidebar: ytd-app attributes changed, re-checking sidebar state.');
                // Add a small delay to ensure the UI has settled after a change
                setTimeout(expandSidebar, 100);
            }
            // Also, check for childList changes on the body or ytd-app to catch major UI re-renders.
            // This is a broader check but can be useful if the structure changes significantly.
            if (mutation.type === 'childList' && (mutation.target === document.body || mutation.target.tagName === 'YTD-APP')) {
                // A small delay might be needed to ensure the DOM is fully rendered after a change
                setTimeout(expandSidebar, 200);
            }
        });
    });

    // Start observing the document body for changes.
    // We observe subtree to catch changes within the entire application layout.
    observer.observe(document.body, {
        attributes: true, // Watch for attribute changes
        childList: true,  // Watch for direct child additions/removals
        subtree: true     // Watch for changes in the entire subtree
    });

    // Initial expansion attempt when the script first loads.
    // A slight delay ensures YouTube's core UI elements are present.
    window.addEventListener('load', () => {
        setTimeout(expandSidebar, 750); // Wait 0.75 seconds after page load
    });

    // Listen for URL changes, which signifies navigation within YouTube's Single Page Application (SPA).
    // This ensures the sidebar is re-checked/expanded when navigating between videos or pages.
    let lastUrl = location.href;
    new MutationObserver(() => {
        if (location.href !== lastUrl) {
            lastUrl = location.href;
            console.log('YouTube Sidebar: URL changed, re-checking sidebar state after navigation.');
            // Only attempt to expand if the new URL is NOT an excluded page.
            // The expandSidebar function itself also has this check for robustness.
            const isExcludedPage = window.location.pathname.startsWith('/watch') ||
                                   window.location.pathname.startsWith('/results');

            if (!isExcludedPage) {
                setTimeout(expandSidebar, 750); // Re-check after navigation with a slightly longer delay
            } else {
                console.log('YouTube Sidebar: New URL is an excluded page. Sidebar expansion script remains disabled for this page.');
            }
        }
    }).observe(document.body, {subtree: true, childList: true}); // Observe body for URL changes
})();
이 게시물에 이메일로 답장하기