YouTube Logo Hover Menu

YouTubeロゴにホバーすると、履歴、後で見る、再生リスト、高評価動画に素早くアクセスできるメニューを表示します。

Bu betiği kurabilmeniz için Tampermonkey, Greasemonkey ya da Violentmonkey gibi bir kullanıcı betiği eklentisini kurmanız gerekmektedir.

Bu betiği yüklemek için Tampermonkey gibi bir uzantı yüklemeniz gerekir.

Bu betiği kurabilmeniz için Tampermonkey ya da Violentmonkey gibi bir kullanıcı betiği eklentisini kurmanız gerekmektedir.

Bu betiği kurabilmeniz için Tampermonkey ya da Userscripts gibi bir kullanıcı betiği eklentisini kurmanız gerekmektedir.

Bu betiği indirebilmeniz için ayrıca Tampermonkey gibi bir eklenti kurmanız gerekmektedir.

Bu komut dosyasını yüklemek için bir kullanıcı komut dosyası yöneticisi uzantısı yüklemeniz gerekecek.

(Zaten bir kullanıcı komut dosyası yöneticim var, kurmama izin verin!)

Bu stili yüklemek için Stylus gibi bir uzantı yüklemeniz gerekir.

Bu stili yüklemek için Stylus gibi bir uzantı kurmanız gerekir.

Bu stili yükleyebilmek için Stylus gibi bir uzantı yüklemeniz gerekir.

Bu stili yüklemek için bir kullanıcı stili yöneticisi uzantısı yüklemeniz gerekir.

Bu stili yüklemek için bir kullanıcı stili yöneticisi uzantısı kurmanız gerekir.

Bu stili yükleyebilmek için bir kullanıcı stili yöneticisi uzantısı yüklemeniz gerekir.

(Zateb bir user-style yöneticim var, yükleyeyim!)

// ==UserScript==
// @name         YouTube Logo Hover Menu
// @name:en      YouTube Logo Hover Menu
// @namespace    https://www.tampermonkey.net/
// @version      2026227
// @description  YouTubeロゴにホバーすると、履歴、後で見る、再生リスト、高評価動画に素早くアクセスできるメニューを表示します。
// @description:en Adds a hover menu to the YouTube logo for quick access to history, watch later, playlists, and liked videos.
// @author       black lagoon
// @match        https://www.youtube.com/*
// @grant        GM_addStyle
// @license      MPL2.0
// ==/UserScript==

(function() {
    'use strict';

    const isJA = navigator.language.startsWith('ja');

    const MENU_ITEMS = [
        {
            id: 'history',
            label: isJA ? '履歴' : 'History',
            path: '/feed/history',
            d: 'M13 3c-4.97 0-9 4.03-9 9H1l3.89 3.89.07.14L9 12H6c0-3.87 3.13-7 7-7s7 3.13 7 7-3.13 7-7 7c-1.93 0-3.68-.79-4.94-2.06l-1.42 1.42C8.27 19.99 10.51 21 13 21c4.97 0 9-4.03 9-9s-4.03-9-9-9zm-1 5v5l4.28 2.54.72-1.21-3.5-2.08V8H12z'
        },
        {
            id: 'watch-later',
            label: isJA ? '後で見る' : 'Watch Later',
            path: '/playlist?list=WL',
            d: 'M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10 10-4.5 10-10S17.5 2 12 2zm4.2 14.2L11 13V7h1.5v5.2l4.5 2.7-.8 1.3z'
        },
        {
            id: 'playlists',
            label: isJA ? '再生リスト' : 'Playlists',
            path: '/feed/library',
            d: 'M22,7H2v1h20V7z M13,12H2v-1h11V12z M13,16H2v-1h11V16z M15,19v-8l7,4L15,19z'
        },
        {
            id: 'liked',
            label: isJA ? '高評価' : 'Liked',
            path: '/playlist?list=LL',
            d: 'M18.77,11h-4.23l1.52-4.94C16.38,5.03,15.54,4,14.38,4c-0.58,0-1.13,0.24-1.53,0.65L7,11H3v10h4h1h9.43 c1.06,0,1.98-0.67,2.26-1.68l1.29-4.73C21.35,13.41,20.41,11,18.77,11z M7,20H4v-8h3V20z M19.98,14.37l-1.29,4.73 C18.59,19.64,18.02,20,17.43,20H8v-8.61l5.83-5.97c0.15-0.15,0.35-0.23,0.55-0.23c0.41,0,0.72,0.37,0.6,0.77L13.46,11h1.08h4.23 c0.54,0,0.85,0.79,0.65,1.29L19.98,14.37z'
        }
    ];

    // --- スタイル適用 ---
    const buildIconStyle = (d) => {
        const svg = `<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='${d}'/></svg>`;
        return `url("data:image/svg+xml;charset=utf-8,${encodeURIComponent(svg)}")`;
    };

    GM_addStyle(`
        #yt-hover-quick-menu {
            position: fixed;
            top: 48px;
            left: 16px;
            background-color: var(--yt-spec-menu-background) !important;
            border: 1px solid var(--yt-spec-10-percent-layer) !important;
            border-radius: 12px !important;
            box-shadow: 0 8px 24px rgba(0,0,0,0.2) !important;
            z-index: 2147483647;
            display: none;
            flex-direction: column;
            width: 220px;
            padding: 8px 0;
        }
        .yt-menu-link {
            display: flex !important;
            align-items: center !important;
            padding: 10px 16px 10px 52px !important;
            color: var(--yt-spec-text-primary) !important;
            text-decoration: none !important;
            font-size: 14px !important;
            font-family: "Roboto", "Arial", sans-serif !important;
            position: relative;
            transition: background 0.1s;
        }
        .yt-menu-link:hover {
            background-color: var(--yt-spec-10-percent-layer) !important;
        }
        .yt-menu-link::before {
            content: '';
            position: absolute;
            left: 16px;
            top: 50%;
            transform: translateY(-50%);
            width: 24px;
            height: 24px;
            background-size: contain;
            background-repeat: no-repeat;
            filter: var(--yt-spec-icon-inactive-contrast-filter) !important;
        }
        ${MENU_ITEMS.map(item => `
            .icon-${item.id}::before { background-image: ${buildIconStyle(item.d)}; }
        `).join('\n')}
    `);

    // --- メニュー生成 ---
    const menu = document.createElement('div');
    menu.id = 'yt-hover-quick-menu';

    MENU_ITEMS.forEach(item => {
        const a = document.createElement('a');
        a.href = item.path;
        a.className = `yt-menu-link icon-${item.id}`;
        a.textContent = item.label;
        menu.appendChild(a);
    });
    document.body.appendChild(menu);

    const handleMouseOver = (e) => {
        const logo = document.querySelector('ytd-topbar-logo-renderer');
        // ロゴコンテナ内、もしくはメニュー自体へのホバーを判定
        if ((logo && logo.contains(e.target))) {
            menu.style.display = 'flex';
        } else if (!menu.contains(e.target)) {
            menu.style.display = 'none';
        }
    };

    document.addEventListener('mouseover', handleMouseOver, { passive: true });
    menu.addEventListener('mouseleave', () => menu.style.display = 'none');

})();