Display a menu showing History, Watch Later, Playlists, and likes when hovering over the YouTube logo.
// ==UserScript==
// @name YouTube QuickLink Menu
// @name:en YouTube QuickLink Menu
// @namespace https://www.tampermonkey.net/
// @version 1.2.1
// @description YouTubeロゴにホバーで履歴・後で見る・再生リスト・高評価を表示するメニューを表示する
// @description:en Display a menu showing History, Watch Later, Playlists, and likes when hovering over the YouTube logo.
// @author black lagoon
// @match https://www.youtube.com/*
// @license MIT
// @grant none
// ==/UserScript==
(function() {
'use strict';
// 言語判定
const isJapanese = navigator.language.startsWith('ja') || document.documentElement.lang === 'ja';
// メニュー項目
const menuItems = [
{
text: isJapanese ? '履歴' : 'History',
url: '/feed/history',
icon: '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'
},
{
text: isJapanese ? '後で見る' : 'Watch Later',
url: '/playlist?list=WL',
icon: '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'
},
{
text: isJapanese ? '再生リスト' : 'Playlists',
url: '/feed/library', // 厳密にはマイページ等の再生リスト一覧
icon: 'M22,7H2v1h20V7z M13,12H2v-1h11V12z M13,16H2v-1h11V16z M15,19v-8l7,4L15,19z'
},
{
text: isJapanese ? '高く評価した動画' : 'Liked Videos',
url: '/playlist?list=LL',
icon: '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 style = document.createElement('style');
style.innerHTML = `
#custom-menu-wrapper {
position: relative;
display: inline-block;
}
#custom-hover-menu {
position: absolute;
top: 40px;
left: 0;
background: var(--yt-spec-menu-background, #282828);
border: 1px solid var(--yt-spec-10-percent-layer, rgba(255,255,255,0.1));
border-radius: 12px;
box-shadow: 0 8px 24px rgba(0,0,0,0.5);
display: none;
flex-direction: column;
padding: 8px 0;
z-index: 9999;
min-width: 220px;
}
#custom-menu-wrapper:hover #custom-hover-menu {
display: flex;
}
.custom-menu-item {
display: flex;
align-items: center;
padding: 10px 16px;
color: var(--yt-spec-text-primary, #fff);
text-decoration: none;
font-size: 14px;
font-family: "Roboto", "Arial", sans-serif;
transition: background-color 0.2s;
}
.custom-menu-item:hover {
background-color: var(--yt-spec-10-percent-layer, rgba(255,255,255,0.1));
}
.custom-menu-icon {
margin-right: 16px;
fill: var(--yt-spec-text-primary, #fff);
width: 24px;
height: 24px;
flex-shrink: 0;
}
`;
document.head.appendChild(style);
const initMenu = () => {
const logoContainer = document.querySelector('ytd-topbar-logo-renderer');
if (!logoContainer || document.getElementById('custom-menu-wrapper')) return;
const wrapper = document.createElement('div');
wrapper.id = 'custom-menu-wrapper';
logoContainer.parentNode.insertBefore(wrapper, logoContainer);
wrapper.appendChild(logoContainer);
const menu = document.createElement('div');
menu.id = 'custom-hover-menu';
menuItems.forEach(item => {
const link = document.createElement('a');
link.href = item.url;
link.className = 'custom-menu-item';
link.innerHTML = `
<svg viewBox="0 0 24 24" class="custom-menu-icon"><path d="${item.icon}"></path></svg>
<span>${item.text}</span>
`;
menu.appendChild(link);
});
wrapper.appendChild(menu);
};
const observer = new MutationObserver(initMenu);
observer.observe(document.body, { childList: true, subtree: true });
initMenu();
})();