Removes YouTube’s new “Delhi” player experiment flags to restore the old video player UI. In english, this userscript brings back the Youtube UI we all know and love. Credits go to Jonny Buchanan at the "Control Panel for Youtube" extension/project. This was developed due to many users like myself wanting a free method to get rid of the new video player change Youtube has forced on us. This userscript also comes with Return Youtube Dislike and many tweaks, all of which are toggleable.
当前为
// ==UserScript==
// @name OldYTPlayer | YouTube Old Player UI Pre-2025 & Minimal Tweaks
// @namespace https://greasyfork.org/
// @match https://www.youtube.com/*
// @license MIT
// @author DudeAint
// @grant none
// @run-at document-start
// @description Removes YouTube’s new “Delhi” player experiment flags to restore the old video player UI. In english, this userscript brings back the Youtube UI we all know and love. Credits go to Jonny Buchanan at the "Control Panel for Youtube" extension/project. This was developed due to many users like myself wanting a free method to get rid of the new video player change Youtube has forced on us. This userscript also comes with Return Youtube Dislike and many tweaks, all of which are toggleable.
// @version 0.1
// @icon https://files.catbox.moe/tac4lf.png
// @supportURL http://greasyfork.org/en/scripts/553368-oldytplayer-youtube-old-player-ui-pre-2025-minimal-tweaks/feedback
// ==/UserScript==
/*
Information & Set-Up
This userscript restores the old Youtube UI player (Remove Delhi Experiments).
Supported Devices & Extensions:
You can use it on PC on Chrome/FireFox/Opera/Edge with Tampermonkey/Scriptcat/Violentmonkey [Free].
You can use it on MacOS on Safari with Stay for Safari [Free].
You can use it on iOS on Safari with Stay for Safari [Free].
Note: unfortunately, this will stop working when Youtube removes the old player UI.
Credits go to "Control Panel for Youtube" for finding this: https://github.com/insin/control-panel-for-youtube/
More information on features are on the main page.
You can use this code in your own projects, if you would like.
If you are reading, please give a good feedback on my page, as I update regularly.
*/
(function () { 'use strict';
try {
const CONFIG_TOGGLES = [
{
id: 'revert_player',
name: 'Revert Old Youtube Player',
desc: 'Restores the pre-2025 player UI and hides the new fullscreen UI. May require a refresh.',
iconName: 'home',
promptRefresh: true,
onChange: (state) => {
if (state) {
robustRemoveDelhiFlagsWithRetries();
applyFullscreenHideCSS();
} else {
removeFullscreenHideCSS();
}
}
},
{
id: 'remove_ai_summary',
name: 'Remove AI Summary',
desc: 'Hides the AI-generated video summary block and the "Ask" AI button. No refresh needed.',
iconName: 'summarize',
promptRefresh: false,
onChange: (on) => { if (on) applyRemoveAISummaryCSS(); else removeRemoveAISummaryCSS(); }
},
{
id: 'enable_dislikes',
name: 'Enable Dislikes',
desc: 'Shows community dislike counts via Return YouTube Dislike. No refresh needed.',
iconName: 'thumb_down',
promptRefresh: false,
onChange: (on) => { try { on ? RYD.start() : RYD.stop(); } catch(_){} }
}
];
// Setting blocks open a nested popup with its own toggles
const CONFIG_BLOCKS = [
{
type: 'block',
id: 'annoyances',
name: 'Annoyances',
desc: 'Hide little nuisances in the player.',
iconName: 'block', // material icon name
/** Features inside this setting block */
children: [
{
id: 'remove_hide_button',
name: 'Remove Hide Button',
desc: 'Hides the endscreen "Hide" button overlay shown at video end.',
iconName: 'visibility_off',
promptRefresh: false,
onChange: (on)=>{ if(on) applyRemoveHideButtonCSS(); else removeRemoveHideButtonCSS(); }
},
{
id: 'remove_pink',
name: 'Remove Pink Gradient',
desc: 'Reverts the pink progress bar to the original YouTube color.',
iconName: 'format_color_reset',
promptRefresh: false,
onChange: (on) => { if (on) applyRemovePinkCSS(); else removeRemovePinkCSS(); }
},
{
id: 'hide_sponsored',
name: 'Hide Sponsored Ads',
desc: 'Hides ad panels, sponsored banners, paid content overlays, merch, offers, channel watermarks, and promoted sections.',
iconName: 'money_off',
promptRefresh: false,
onChange: (on) => { if (on) applyHideSponsoredCSS(); else removeHideSponsoredCSS(); }
},
{
id: 'hide_shorts',
name: 'Hide Shorts',
desc: 'Hides YouTube Shorts from home, search, side menu, related, and more.',
iconName: 'hide_source',
promptRefresh: false,
onChange: (on) => { if (on) applyHideShortsCSS(); else removeHideShortsCSS(); }
},
{
id: 'hide_share_thanks_clip',
name: 'Hide Share/Thanks/Clip Buttons',
desc: 'Hides Share, Thanks, and Clip buttons on video pages and menus.',
iconName: 'ios_share',
promptRefresh: false,
onChange: (on) => {
if (on) applyHideShareThanksClipCSS();
else removeHideShareThanksClipCSS();
}
}
]
},
{
type: 'block',
id: 'tweaks',
name: 'Tweaks',
desc: 'Change the way Youtube looks.',
iconName: 'tune', // material icon name
children: [
{
type: 'select',
id: 'search_thumb_size',
name: 'Search Thumbnails Size',
desc: 'Adjusts thumbnail & avatar sizes on search pages.',
iconName: 'photo_size_select_large',
promptRefresh: false,
options: [
{ value: 'small', label: 'Small' },
{ value: 'medium', label: 'Medium' },
{ value: 'large', label: 'Large (Default)' }
],
default: 'large',
onChange: (value) => { applySearchThumbSizeCSS(value); }
},
{
type: 'select',
id: 'minimum_grid_items',
name: 'Minimum Grid Items Per Row',
desc: 'Force a minimum number of videos per row on Home and Subscriptions pages.',
iconName: 'view_column',
promptRefresh: true,
options: [
{ value: 'auto', label: 'Auto (Default)' },
{ value: '6', label: '6 per row' },
{ value: '5', label: '5 per row' },
{ value: '4', label: '4 per row' },
{ value: '3', label: '3 per row' },
{ value: '2', label: '2 per row' }
],
default: 'auto',
onChange: (val) => applyMinimumGridItemsCSS(val)
}
] }
];
// Defaults: only revert_player ON by default
const DEFAULT_CONFIG = { revert_player: true };
// Helper: flatten all toggles (booleans) including those inside blocks
function getAllToggles(){
const nested = [];
for (const b of CONFIG_BLOCKS) if (b && Array.isArray(b.children)) nested.push(...b.children.filter(c=>!c.type || c.type==='toggle'));
return [...CONFIG_TOGGLES, ...nested];
}
// Fullscreen “Delhi” UI hide defaults (auto-applied when revert_player is ON). You can turn this off if you'd like, I haven't included a toggle for this yet.
const HIDE_FULLSCREEN_CONFIG = {
playerHideFullScreenMoreVideos: true,
playerHideFullScreenControls: true
};
/* ============================ LIGHT STORAGE ========================= */
const STORAGE_PREFIX = 'OldYTPlayer:toggle:'; // booleans only
const APPLIED_PREFIX = 'OldYTPlayer:applied:'; // booleans only
const VALUE_PREFIX = 'OldYTPlayer:value:'; // string values (selects, etc.)
const LS = window.localStorage;
// boolean toggles
function storageGet(id){ try{ return LS.getItem(STORAGE_PREFIX+id)==='1'; }catch(_){ return false; } }
function storageSet(id,v){ try{ LS.setItem(STORAGE_PREFIX+id, v?'1':'0'); }catch(_){} }
function storageHas(id){ try{ return LS.getItem(STORAGE_PREFIX+id)!==null; }catch(_){ return false; } }
function appliedGet(id){ try{ return LS.getItem(APPLIED_PREFIX+id)==='1'; }catch(_){ return storageGet(id); } }
function appliedSet(id,v){ try{ LS.setItem(APPLIED_PREFIX+id, v?'1':'0'); }catch(_){} }
function appliedSeedFromCurrent(){ for (const cfg of getAllToggles()) appliedSet(cfg.id, storageGet(cfg.id)); }
// value selects
function storageGetVal(id, def){ try{ const v=LS.getItem(VALUE_PREFIX+id); return v!==null ? v : def; }catch(_){ return def; } }
function storageSetVal(id, v){ try{ LS.setItem(VALUE_PREFIX+id, String(v)); }catch(_){} }
function storageHasVal(id){ try{ return LS.getItem(VALUE_PREFIX+id)!==null; }catch(_){ return false; } }
// seed toggle defaults if missing
for (const cfg of getAllToggles()){
if (!storageHas(cfg.id)) {
const def = Object.prototype.hasOwnProperty.call(DEFAULT_CONFIG, cfg.id) ? !!DEFAULT_CONFIG[cfg.id] : false;
storageSet(cfg.id, def);
}
}
// seed select defaults
for (const b of CONFIG_BLOCKS){
if (!b.children) continue;
for (const c of b.children){
if (c && c.type==='select'){
if (!storageHasVal(c.id)) storageSetVal(c.id, c.default);
}
}
}
/** Reset refresh state on every run (fresh load). */
appliedSeedFromCurrent();
/* ==================== DELHI FLAG REMOVAL (optimized) =============== */
const DELHI_STYLE_RE = /ytp-fullscreen-(quick-actions|grid)/;
let didStripDelhiStyles = false;
function tryRemoveDelhiFlagsOnce() {
try {
const yt = window.yt;
let mod = 0;
if (yt && yt.config_ && yt.config_.WEB_PLAYER_CONTEXT_CONFIGS) {
const cfgs = yt.config_.WEB_PLAYER_CONTEXT_CONFIGS;
for (const k in cfgs) {
const c = cfgs[k];
if (c && typeof c.serializedExperimentFlags === 'string') {
const before = c.serializedExperimentFlags;
if (!before.includes('delhi_modern_web_player')) {
if (before.includes('delhi_modern_web_player_icons')) {
const after = before
.replace(/&?delhi_modern_web_player_icons=true/g, '')
.replace(/&&+/g, '&').replace(/^&+/, '').replace(/&+$/, '');
if (after !== before) { c.serializedExperimentFlags = after; mod++; }
}
} else {
const after = before
.replace(/&?delhi_modern_web_player=true/g, '')
.replace(/&?delhi_modern_web_player_icons=true/g, '')
.replace(/&&+/g, '&').replace(/^&+/, '').replace(/&+$/, '');
if (after !== before) { c.serializedExperimentFlags = after; mod++; }
}
}
}
}
const removed = removeFullscreenQuickActions();
return mod + (removed ? 1 : 0);
} catch (_) { return 0; }
}
function removeFullscreenQuickActions() {
let removed = false;
const hasTargets = document.querySelector('.ytp-fullscreen-quick-actions, .ytp-fullscreen-grid');
if (!didStripDelhiStyles || hasTargets) {
const styles = document.getElementsByTagName('style');
for (let i = styles.length - 1; i >= 0; i--) {
const s = styles[i];
try {
const txt = s.textContent;
if (txt && DELHI_STYLE_RE.test(txt)) {
s.remove();
removed = true;
didStripDelhiStyles = true;
}
} catch(_) {}
}
}
if (hasTargets) {
const q = document.querySelectorAll('.ytp-fullscreen-quick-actions, .ytp-fullscreen-grid');
for (let i=0;i<q.length;i++) { try{ q[i].remove(); removed = true; }catch(_){} }
}
return removed;
}
function robustRemoveDelhiFlagsWithRetries() {
if (tryRemoveDelhiFlagsOnce() > 0) return true;
let tries = 0, max = 60;
const t = setInterval(() => { tries++; const n = tryRemoveDelhiFlagsOnce(); if (n > 0 || tries >= max) clearInterval(t); }, 200);
const obs = new MutationObserver((muts) => {
for (let i=0;i<muts.length;i++){
const m = muts[i];
for (let j=0;j<m.addedNodes.length;j++){
const n = m.addedNodes[j];
if (n && n.nodeType === 1) {
const el = n;
if (el.matches && (el.matches('.ytp-fullscreen-quick-actions, .ytp-fullscreen-grid') ||
(el.tagName === 'STYLE' && DELHI_STYLE_RE.test(el.textContent||'')) )) { removeFullscreenQuickActions(); return; }
if (el.querySelector && el.querySelector('.ytp-fullscreen-quick-actions, .ytp-fullscreen-grid')) { removeFullscreenQuickActions(); return; }
}
}
}
});
obs.observe(document.documentElement, { childList:true, subtree:true });
return false;
}
/* =============== Fullscreen hide CSS (existing feature) =============== */
const HIDE_STYLE_ID = 'oldytplayer-hide-fullscreen-css';
function isMobileUA(){ try{ return /Mobi|Android|iPhone|iPad|iPod/i.test(navigator.userAgent || ''); }catch(_){ return false; } }
function isDesktop(){ return !isMobileUA(); }
function applyFullscreenHideCSS() {
removeFullscreenHideCSS();
const desktop = isDesktop();
const mobile = !desktop;
const hideCssSelectors = [];
const cssRules = [];
if (HIDE_FULLSCREEN_CONFIG.playerHideFullScreenMoreVideos) {
if (desktop) {
hideCssSelectors.push('.ytp-fullscreen-grid');
cssRules.push(`
#movie_player.ytp-delhi-modern { --ytp-grid-scroll-percentage: 0 !important; }
.ytp-delhi-modern.ytp-grid-scrolling .ytp-chrome-bottom { bottom: 0 !important; opacity: 1 !important; }
.ytp-delhi-modern .ytp-gradient-bottom { display: none !important; }
`);
}
}
if (HIDE_FULLSCREEN_CONFIG.playerHideFullScreenControls) {
if (desktop) hideCssSelectors.push('.ytp-fullscreen-quick-actions');
}
if (HIDE_FULLSCREEN_CONFIG.playerHideFullScreenControls &&
HIDE_FULLSCREEN_CONFIG.playerHideFullScreenMoreVideos) {
if (mobile) {
cssRules.push(`
body[faux-fullscreen="true"] .enable-fullscreen-controls.fs-watch-system .watch-page-progress-bar { bottom: 0 !important; }
body[faux-fullscreen="true"] .enable-fullscreen-controls.fs-watch-system .player-controls-bottom { bottom: 30px !important; }
`);
}
}
const style = document.createElement('style'); style.id = HIDE_STYLE_ID;
const hideBlock = hideCssSelectors.length ? `${hideCssSelectors.join(',\n')} { display: none !important; }` : '';
const allCss = [hideBlock, ...cssRules].join('\n');
try{ style.appendChild(document.createTextNode(allCss)); }catch(_){ style.textContent = allCss; }
(document.head || document.documentElement).appendChild(style);
}
function removeFullscreenHideCSS() { const s = document.getElementById(HIDE_STYLE_ID); if (s) try{ s.remove(); }catch(_){} }
/* ==================== Remove AI Summary (CSS-only) ================== */
const AI_SUMMARY_STYLE_ID = 'oldytplayer-hide-aisummary-css';
function applyRemoveAISummaryCSS() {
removeRemoveAISummaryCSS();
const css = `
ytd-expandable-metadata-renderer[has-video-summary] { display: none !important; }
#flexible-item-buttons button[aria-label^="Ask" i],
ytd-menu-renderer button[aria-label^="Ask" i] { display: none !important; }
`;
const style = document.createElement('style'); style.id = AI_SUMMARY_STYLE_ID;
try { style.appendChild(document.createTextNode(css)); } catch(_) { style.textContent = css; }
(document.head || document.documentElement).appendChild(style);
}
function removeRemoveAISummaryCSS() {
const s = document.getElementById(AI_SUMMARY_STYLE_ID);
if (s) try{ s.remove(); }catch(_){}
}
/* ==================== Hide Shorts Logic (CSS-only) ================== */
function applyHideShortsCSS() {
const style = document.createElement('style');
style.id = 'hide-shorts-style';
const selectors = [];
selectors.push('.HideShorts');
if (isDesktop()) {
selectors.push(
`ytd-guide-entry-renderer:has(> a[title="Shorts"])`,
`ytd-mini-guide-entry-renderer[aria-label="Shorts"]`,
'ytd-rich-section-renderer:has(> #content > ytd-rich-shelf-renderer[is-shorts])',
'ytd-browse[page-subtype="home"] ytd-rich-grid-group',
'ytd-browse[page-subtype="home"] ytd-rich-item-renderer[is-slim-media][rendered-from-rich-grid]',
`yt-chip-cloud-chip-renderer:has(> #chip-container > yt-formatted-string[title="Shorts"])`,
'ytd-browse:not([page-subtype="history"]) ytd-reel-shelf-renderer',
'ytd-search ytd-reel-shelf-renderer',
'ytd-search grid-shelf-view-model',
'ytd-browse:not([page-subtype="history"]) ytd-video-renderer:has(a[href^="/shorts"])',
'ytd-search ytd-video-renderer:has(a[href^="/shorts"])',
'#structured-description ytd-reel-shelf-renderer',
'#related ytd-reel-shelf-renderer',
'#related ytd-compact-video-renderer:has(a[href^="/shorts"])'
);
} else {
selectors.push(
'ytm-pivot-bar-item-renderer:has(> div.pivot-shorts)',
'ytm-rich-section-renderer:has(ytm-reel-shelf-renderer)',
'ytm-rich-section-renderer:has(ytm-shorts-lockup-view-model)',
'.tab-content[tab-identifier="FEsubscriptions"] ytm-item-section-renderer:has(ytm-reel-shelf-renderer)',
'ytm-search lazy-list > ytm-reel-shelf-renderer',
'ytm-search ytm-video-with-context-renderer:has(a[href^="/shorts"])',
'ytm-structured-description-content-renderer ytm-reel-shelf-renderer',
'ytm-item-section-renderer[section-identifier="related-items"] ytm-video-with-context-renderer:has(a[href^="/shorts"])'
);
}
style.textContent = selectors.map(sel => `${sel} { display: none !important; }`).join('\n');
document.head.appendChild(style);
}
function removeHideShortsCSS() { document.getElementById('hide-shorts-style')?.remove(); }
/* ==================== Hide Sponsored Logic (CSS-only) ================== */
function applyHideSponsoredCSS() {
const style = document.createElement('style');
style.id = 'hide-sponsored-style';
const selectors = [];
if (isDesktop()) {
selectors.push(
'.annotation.iv-branding',
'#masthead-ad',
'#ticket-shelf',
'ytd-merch-shelf-renderer',
'#offer-module',
'#big-yoodle ytd-statement-banner-renderer',
'ytd-rich-section-renderer:has(> #content > ytd-statement-banner-renderer)',
'ytd-rich-section-renderer:has(> #content > ytd-rich-shelf-renderer[has-paygated-featured-badge])',
'ytd-rich-section-renderer:has(> #content > ytd-brand-video-shelf-renderer)',
'ytd-rich-section-renderer:has(> #content > ytd-brand-video-singleton-renderer)',
'ytd-rich-section-renderer:has(> #content > ytd-inline-survey-renderer)',
'tp-yt-paper-dialog:has(> #mealbar-promo-renderer)',
'ytd-rich-item-renderer:has(> .ytd-rich-item-renderer > ytd-ad-slot-renderer)',
'ytd-search-pyv-renderer.ytd-item-section-renderer',
'ytd-ad-slot-renderer.ytd-item-section-renderer',
'ytd-engagement-panel-section-list-renderer[target-id="engagement-panel-ads"]',
'#movie_player .ytp-suggested-action',
'#below #panels',
'.ytp-ad-action-interstitial',
'.ytp-paid-content-overlay',
'ytm-paid-content-overlay-renderer',
'#player-ads',
'#items > ytd-ad-slot-renderer'
);
if (storageGet('hide_share_thanks_clip')) {
selectors.push('#sponsor-button');
}
} else {
selectors.push(
'ytm-statement-banner-renderer',
'ytm-rich-item-renderer:has(> ad-slot-renderer)',
'#ticket-shelf',
'ytd-merch-shelf-renderer',
'#offer-module',
'.mealbar-promo-renderer',
'ytm-search ytm-item-section-renderer:has(> lazy-list > ad-slot-renderer)',
'ytm-paid-content-overlay-renderer',
'ytm-companion-slot:has(> ytm-companion-ad-renderer)',
'ytm-item-section-renderer:has(> lazy-list > ad-slot-renderer:only-child)',
'ytm-item-section-renderer[section-identifier="related-items"] > lazy-list > ad-slot-renderer'
);
}
style.textContent = selectors.map(sel => `${sel} { display: none !important; }`).join('\n');
document.head.appendChild(style);
}
function removeHideSponsoredCSS() { document.getElementById('hide-sponsored-style')?.remove(); }
/* ==================== Hide Share Thanks Logic (CSS-only) ================== */
function applyHideShareThanksClipCSS() {
const style = document.createElement('style');
style.id = 'oldyt-hide-share-thanks-style';
const selectors = [];
if (isDesktop()) {
selectors.push(
// Video buttons
'ytd-menu-renderer yt-button-view-model:has(> button-view-model > button[aria-label="Share"])',
'ytd-menu-renderer yt-button-view-model:has(> button-view-model > button[aria-label="Thanks"])',
'ytd-menu-renderer yt-button-view-model:has(> button-view-model > button[aria-label="Clip"])',
'button.ytp-share-button',
'.oldyt-hide-share-thanks-clip',
'#share-button.ytd-reel-player-overlay-renderer',
'yt-player-quick-action-buttons button[aria-label="Share"]'
);
if (storageGet('hide_sponsored')) {
selectors.push('#sponsor-button');
}
} else {
selectors.push(
// Mobile video buttons
'ytm-slim-video-action-bar-renderer button-view-model:has(button[aria-label="Share"])',
'.reel-player-overlay-actions .icon-shorts_share',
'player-fullscreen-action-menu ytm-slim-metadata-button-renderer:has(button[aria-label="Share"])'
);
}
style.textContent = selectors.map(sel => `${sel} { display: none !important; }`).join('\n');
document.head.appendChild(style);
}
function removeHideShareThanksClipCSS() {
document.getElementById('oldyt-hide-share-thanks-style')?.remove();
}
/* ==================== Remove Pink Logic (CSS-only) ================== */
function applyRemovePinkCSS() {
const style = document.createElement('style');
style.id = 'remove-pink-style';
style.textContent = `
.ytp-play-progress,
.thumbnail-overlay-resume-playback-progress,
.ytChapteredProgressBarChapteredPlayerBarChapterSeen,
.ytChapteredProgressBarChapteredPlayerBarFill,
.ytProgressBarLineProgressBarPlayed,
.ytThumbnailOverlayProgressBarHostWatchedProgressBarSegment {
background: #f03 !important;
}
.ytp-play-progress,
#progress.ytd-thumbnail-overlay-resume-playback-renderer,
.ytThumbnailOverlayProgressBarHostWatchedProgressBarSegment,
.ytChapteredProgressBarChapteredPlayerBarChapterSeen,
.ytChapteredProgressBarChapteredPlayerBarFill,
.ytProgressBarLineProgressBarPlayed,
#progress.yt-page-navigation-progress,
.progress-bar-played.ytd-progress-bar-line {
background: #f03 !important;
}
`;
document.head.appendChild(style);
}
function removeRemovePinkCSS() { document.getElementById('remove-pink-style')?.remove(); }
/* ==================== NEW: Hide endscreen "Hide" button ============= */
const HIDE_ENDSCREEN_BTN_STYLE_ID = 'oldytplayer-hide-endscreen-btn-css';
function applyRemoveHideButtonCSS(){
removeRemoveHideButtonCSS();
const css = `.ytp-ce-hide-button-container { display: none !important; }`;
const st = document.createElement('style'); st.id = HIDE_ENDSCREEN_BTN_STYLE_ID;
try{ st.appendChild(document.createTextNode(css)); }catch(_){ st.textContent = css; }
(document.head||document.documentElement).appendChild(st);
}
function removeRemoveHideButtonCSS(){ document.getElementById(HIDE_ENDSCREEN_BTN_STYLE_ID)?.remove(); }
/* ==================== Grid Items (dropdown) ========= */
const GRID_ITEMS_STYLE_ID = 'oldytplayer-minimum-grid-css';
function applyMinimumGridItemsCSS(value) {
removeMinimumGridItemsCSS();
if (value === 'auto') return; // Don't override
const gridItemsPerRow = Number(value);
if (isNaN(gridItemsPerRow)) return;
const exclude = [];
for (let i = 6; i > gridItemsPerRow; i--) {
exclude.push(`[elements-per-row="${i}"]`);
}
const css = `
ytd-browse:is([page-subtype="home"], [page-subtype="subscriptions"]) ytd-rich-grid-renderer${exclude.length ? `:not(${exclude.join(', ')})` : ''} {
--ytd-rich-grid-items-per-row: ${gridItemsPerRow} !important;
}
`;
const style = document.createElement('style');
style.id = GRID_ITEMS_STYLE_ID;
try { style.appendChild(document.createTextNode(css)); } catch { style.textContent = css; }
(document.head || document.documentElement).appendChild(style);
}
function removeMinimumGridItemsCSS() {
document.getElementById(GRID_ITEMS_STYLE_ID)?.remove();
}
/* ==================== NEW: Search thumbnail size (dropdown) ========= */
/* Uses snippet provided; applies only when not "large". */
const SEARCH_THUMB_STYLE_ID = 'oldytplayer-search-thumb-css';
function applySearchThumbSizeCSS(size){
removeSearchThumbSizeCSS();
if (size === 'large') return; // no override == large (native)
const px = ({ medium: 420, small: 360 }[size]) || 420;
const css = `
ytd-search ytd-video-renderer ytd-thumbnail.ytd-video-renderer,
ytd-search yt-lockup-view-model .yt-lockup-view-model__content-image,
ytd-search ytd-channel-renderer #avatar-section {
max-width: ${px}px !important;
}
`;
const st = document.createElement('style'); st.id = SEARCH_THUMB_STYLE_ID;
try{ st.appendChild(document.createTextNode(css)); }catch(_){ st.textContent = css; }
(document.head||document.documentElement).appendChild(st);
}
function removeSearchThumbSizeCSS(){ document.getElementById(SEARCH_THUMB_STYLE_ID)?.remove(); }
/* ==================== Return YouTube Dislike (sandbox) ============== */
const RYD = (() => {
const STATE = { OFF: 0, ON: 1 };
let running = STATE.OFF;
const CONFIG = {
showUpdatePopup: false,
disableVoteSubmission: false,
disableLogging: true,
coloredThumbs: false,
coloredBar: false,
colorTheme: "classic",
numberDisplayFormat: "compactShort",
numberDisplayRoundDown: true,
tooltipPercentageMode: "none",
numberDisplayReformatLikes: false,
rateBarEnabled: false
};
const LIKED_STATE = 1, DISLIKED_STATE = 2, NEUTRAL_STATE = 3;
let previousState = NEUTRAL_STATE, likesvalue = 0, dislikesvalue = 0, preNavigateLikeButton = null;
let isMobile = false;
const isShorts = () => location.pathname.startsWith("/shorts");
let mobileDislikes = 0;
let shortsObserver = null, smartimationObserver = null, jsInitCheckTimer = null, mobileInterval = null;
let onNavigateFinishRef = null, originalPush = null, wrappedHistory = false;
let lastLikeBtn = null, lastDislikeBtn = null;
const STYLE_ID = 'oldytplayer-ryd-style';
function injectStyle(){
if (document.getElementById(STYLE_ID)) return;
const css = `
#return-youtube-dislike-bar-container { background: var(--yt-spec-icon-disabled); border-radius: 2px; }
#return-youtube-dislike-bar { background: var(--yt-spec-text-primary); border-radius: 2px; transition: all 0.15s ease-in-out; }
.ryd-tooltip { position: absolute; display: block; height: 2px; bottom: -10px; }
.ryd-tooltip-bar-container { width: 100%; height: 2px; position: absolute; padding-top: 6px; padding-bottom: 12px; top: -6px; }
ytd-menu-renderer.ytd-watch-metadata { overflow-y: visible !important; }
#top-level-buttons-computed { position: relative !important; }
`;
const st = document.createElement('style'); st.id = STYLE_ID;
try { st.appendChild(document.createTextNode(css)); } catch(_) { st.textContent = css; }
(document.head||document.documentElement).appendChild(st);
}
function removeStyle(){ document.getElementById(STYLE_ID)?.remove(); }
function inViewport(el){ const r=el.getBoundingClientRect(),h=innerHeight||document.documentElement.clientHeight,w=innerWidth||document.documentElement.clientWidth; return !(r.top==0&&r.left==0&&r.bottom==0&&r.right==0)&&r.top>=0&&r.left>=0&&r.bottom<=h&&r.right<=w; }
function getButtons(){
if (isShorts()) { const q=document.querySelectorAll(isMobile?"ytm-like-button-renderer":"#like-button > ytd-like-button-renderer"); for (const el of q){ if(inViewport(el)) return el; } }
if (isMobile) return document.querySelector(".slim-video-action-bar-actions .segmented-buttons") ?? document.querySelector(".slim-video-action-bar-actions");
if (document.getElementById("menu-container")?.offsetParent === null){
return document.querySelector("ytd-menu-renderer.ytd-watch-metadata > div") ?? document.querySelector("ytd-menu-renderer.ytd-video-primary-info-renderer > div");
} else { return document.getElementById("menu-container")?.querySelector("#top-level-buttons-computed"); }
}
function getDislikeButton(){ const b=getButtons(); if(!b) return null; if (b.children[0]?.tagName==="YTD-SEGMENTED-LIKE-DISLIKE-BUTTON-RENDERER"){ return b.children[0].children[1] ?? document.querySelector("#segmented-dislike-button"); } else { return b.querySelector("segmented-like-dislike-button-view-model") ? b.querySelector("dislike-button-view-model") : b.children[1]; } }
function getLikeButton(){ const b=getButtons(); if(!b) return null; return b.children[0].tagName==="YTD-SEGMENTED-LIKE-DISLIKE-BUTTON-RENDERER" ? (document.querySelector("#segmented-like-button") ?? b.children[0].children[0]) : (b.querySelector("like-button-view-model") ?? b.children[0]); }
function getLikeTextContainer(){ const l=getLikeButton(); return l?.querySelector("#text") ?? l?.getElementsByTagName("yt-formatted-string")[0] ?? l?.querySelector("span[role='text']"); }
function getDislikeTextContainer(){ const d=getDislikeButton(); let r=d?.querySelector("#text") ?? d?.getElementsByTagName("yt-formatted-string")[0] ?? d?.querySelector("span[role='text']"); if(!r){ const s=document.createElement('span'); s.id='text'; s.style.marginLeft='6px'; d?.querySelector('button')?.appendChild(s); d && (d.querySelector('button').style.width='auto'); r=s; } return r; }
function isVideoLiked(){ return isMobile ? (getLikeButton()?.querySelector("button").getAttribute("aria-label")=="true") : getLikeButton()?.classList.contains("style-default-active"); }
function isVideoDisliked(){ return isMobile ? (getDislikeButton()?.querySelector("button").getAttribute("aria-label")=="true") : getDislikeButton()?.classList.contains("style-default-active"); }
function checkForUserAvatarButton(){ if (isMobile) return; return !!document.querySelector("#avatar-btn"); }
function setLikes(n) {
if (isMobile) {
const btn = getButtons()?.children[0]?.querySelector(".button-renderer-text");
if (btn) btn.innerText = n;
return;
}
const likeText = getLikeTextContainer();
if (likeText) likeText.innerText = n;
}
function setDislikes(n) {
if (isMobile) { mobileDislikes = n; return; }
const c = getDislikeTextContainer();
if (!c) return;
c.removeAttribute("is-empty");
if (c.innerText !== n) c.innerText = n;
}
function getLikeCountFromButton(){ try{ if(location.pathname.startsWith('/shorts')) return false; const likeBtn=getLikeButton(); const el=likeBtn?.querySelector("yt-formatted-string#text") ?? likeBtn?.querySelector("button"); const s=el?.getAttribute("aria-label")?.replace(/\D/g,'') ?? ""; return s.length>0?parseInt(s):false; }catch{ return false; } }
function roundDown(num){ if (num<1000) return num; const int=Math.floor(Math.log10(num)-2); const decimal=int+(int%3?1:0); const value=Math.floor(num/10**decimal); return value*10**decimal; }
function numberFormat(n){ const display = CONFIG.numberDisplayRoundDown ? roundDown(n) : n; return Intl.NumberFormat(document.documentElement.lang||navigator.language||'en', {notation: CONFIG.numberDisplayFormat==='standard'?'standard':'compact', compactDisplay: CONFIG.numberDisplayFormat==='compactLong'?'long':'short'}).format(display); }
function createRateBar(likes, dislikes){
if (isMobile || !CONFIG.rateBarEnabled) return;
let rateBar = document.getElementById("return-youtube-dislike-bar-container");
const widthPx = (getLikeButton()?.clientWidth || 52) + ((getDislikeButton()?.clientWidth) ?? 52);
const widthPercent = likes+dislikes>0 ? (likes/(likes+dislikes))*100 : 50;
if (!rateBar) {
const wrap=getButtons(); if(!wrap) return;
wrap.insertAdjacentHTML("beforeend", `
<div class="ryd-tooltip" style="width:${widthPx}px">
<div class="ryd-tooltip-bar-container">
<div id="return-youtube-dislike-bar-container" style="width:100%;height:2px">
<div id="return-youtube-dislike-bar" style="width:${widthPercent}%;height:100%"></div>
</div>
</div>
</div>
`);
const topRow=document.getElementById('top-row'); if(topRow){ topRow.style.borderBottom="1px solid var(--yt-spec-10-percent-layer)"; topRow.style.paddingBottom="10px"; }
} else {
const tip=document.querySelector('.ryd-tooltip'); if(tip) tip.style.width=widthPx+"px";
const bar=document.getElementById('return-youtube-dislike-bar'); if(bar) bar.style.width=widthPercent+"%";
}
}
function setState(){
const id = (()=>{
const u=new URL(location.href), p=u.pathname;
if (p.startsWith('/clip')) return (document.querySelector("meta[itemprop='videoId']")||document.querySelector("meta[itemprop='identifier']"))?.content;
if (p.startsWith('/shorts')) return p.slice(8);
return u.searchParams.get('v');
})();
if (!id) return;
fetch(`https://returnyoutubedislikeapi.com/votes?videoId=${id}`).then(r=>r.json()).then(json=>{
if (!json) return;
const { dislikes, likes } = json;
likesvalue = likes; dislikesvalue = dislikes;
setDislikes(numberFormat(dislikes));
createRateBar(likes, dislikes);
}).catch(()=>{});
}
function updateDOMDislikes(){ setDislikes(numberFormat(dislikesvalue)); createRateBar(likesvalue, dislikesvalue); }
function likeClicked(){ if(checkForUserAvatarButton()===true){ if(previousState===1){ likesvalue--; updateDOMDislikes(); previousState=3; } else if(previousState===2){ likesvalue++; dislikesvalue--; updateDOMDislikes(); previousState=1; } else { likesvalue++; updateDOMDislikes(); previousState=1; } const n=getLikeCountFromButton(); if(n!==false) setLikes(numberFormat(n)); } }
function dislikeClicked(){ if(checkForUserAvatarButton()===true){ if(previousState===3){ dislikesvalue++; updateDOMDislikes(); previousState=2; } else if(previousState===2){ dislikesvalue--; updateDOMDislikes(); previousState=3; } else { likesvalue--; dislikesvalue++; updateDOMDislikes(); previousState=2; const n=getLikeCountFromButton(); if(n!==false) setLikes(numberFormat(n)); } } }
function isVideoLoaded(){
if (isMobile) return document.getElementById("player")?.getAttribute("loading")=="false";
const u=new URL(location.href), p=u.pathname, vid = p.startsWith('/shorts')?p.slice(8):u.searchParams.get('v');
return !!(document.querySelector(`ytd-watch-grid[video-id='${vid}']`) || document.querySelector(`ytd-watch-flexy[video-id='${vid}']`) || document.querySelector('#player[loading="false"]:not([hidden])'));
}
function setEventListeners(){
function check(){ if (location.pathname.startsWith('/shorts') || (getButtons()?.offsetParent && isVideoLoaded())) {
const buttons=getButtons(), dislikeButton=getDislikeButton(), likeBtn=getLikeButton();
if (preNavigateLikeButton !== likeBtn && dislikeButton){
try{
likeBtn?.addEventListener('click', likeClicked, {passive:true});
dislikeButton?.addEventListener('click', dislikeClicked, {passive:true});
likeBtn?.addEventListener('touchstart', likeClicked, {passive:true});
dislikeButton?.addEventListener('touchstart', dislikeClicked, {passive:true});
dislikeButton?.addEventListener('focusin', updateDOMDislikes, {passive:true});
dislikeButton?.addEventListener('focusout', updateDOMDislikes, {passive:true});
preNavigateLikeButton = likeBtn; lastLikeBtn=likeBtn; lastDislikeBtn=dislikeButton;
const smart = buttons?.querySelector("yt-smartimation");
if (smart) { smartimationObserver && smartimationObserver.disconnect(); smartimationObserver=new MutationObserver(updateDOMDislikes); smartimationObserver.observe(smart,{attributes:true,subtree:true,childList:true}); }
}catch{}
}
if (dislikeButton){ setState(); if (jsInitCheckTimer) { clearInterval(jsInitCheckTimer); jsInitCheckTimer=null; } }
} }
if (jsInitCheckTimer) clearInterval(jsInitCheckTimer);
jsInitCheckTimer=setInterval(check, 111);
}
function onNavigateFinish(){ setEventListeners(); }
function start(){
if (running===STATE.ON) return;
running=STATE.ON;
isMobile = (location.hostname==='m.youtube.com');
injectStyle();
onNavigateFinishRef = onNavigateFinish;
window.addEventListener('yt-navigate-finish', onNavigateFinishRef, true);
setEventListeners();
if (isMobile){
if (!wrappedHistory){
originalPush = history.pushState;
history.pushState = function(...args){ setEventListeners(args[2]); return originalPush.apply(history,args); };
wrappedHistory = true;
}
if (!mobileInterval){
mobileInterval = setInterval(()=>{ const d=getDislikeButton(); if(!d) return; const t=d.querySelector(".button-renderer-text"); if (!t){ const c=getDislikeTextContainer(); if(c) c.innerText=mobileDislikes; } else { t.innerText=mobileDislikes; } }, 1000);
}
}
}
function stop(){
if (running===STATE.OFF) return;
running=STATE.OFF;
if (onNavigateFinishRef){ window.removeEventListener('yt-navigate-finish', onNavigateFinishRef, true); onNavigateFinishRef=null; }
if (wrappedHistory && originalPush){ history.pushState = originalPush; wrappedHistory=false; originalPush=null; }
if (mobileInterval){ clearInterval(mobileInterval); mobileInterval=null; }
try{ shortsObserver && shortsObserver.disconnect(); }catch(_){} shortsObserver=null;
try{ smartimationObserver && smartimationObserver.disconnect(); }catch(_){} smartimationObserver=null;
try{
lastLikeBtn && lastLikeBtn.removeEventListener('click', likeClicked);
lastLikeBtn && lastLikeBtn.removeEventListener('touchstart', likeClicked);
lastDislikeBtn && lastDislikeBtn.removeEventListener('click', dislikeClicked);
lastDislikeBtn && lastDislikeBtn.removeEventListener('touchstart', dislikeClicked);
lastDislikeBtn && lastDislikeBtn.removeEventListener('focusin', updateDOMDislikes);
lastDislikeBtn && lastDislikeBtn.removeEventListener('focusout', updateDOMDislikes);
}catch(_){}
lastLikeBtn=lastDislikeBtn=null; preNavigateLikeButton=null;
try{ const tip=document.querySelector('.ryd-tooltip'); tip && tip.remove(); const topRow=document.getElementById('top-row'); if(topRow){ topRow.style.borderBottom=''; topRow.style.paddingBottom=''; } }catch(_){}
removeStyle();
}
return { start, stop };
})();
/* ========== Apply toggles/values immediately at load =============== */
if (storageGet('revert_player')) { robustRemoveDelhiFlagsWithRetries(); applyFullscreenHideCSS(); }
if (storageGet('remove_ai_summary')) applyRemoveAISummaryCSS();
if (storageGet('enable_dislikes')) RYD.start();
if (storageGet('remove_hide_button')) applyRemoveHideButtonCSS();
if (storageGet('remove_pink')) applyRemovePinkCSS();
if (storageGet('hide_sponsored')) applyHideSponsoredCSS();
if (storageGet('hide_shorts')) applyHideShortsCSS();
applySearchThumbSizeCSS(storageGetVal('search_thumb_size','medium'));
applyMinimumGridItemsCSS(storageGetVal('minimum_grid_items', 'auto'));
if (storageGet('hide_share_thanks_clip')) applyHideShareThanksClipCSS();
/* ============================ DOM/STYLE ============================= */
const STYLE_ID = 'oldytplayer-style-v077'; // keep same look
function safeAppend(p,n){ try{ if(p && n && n.nodeType===1) p.appendChild(n); }catch(_){} }
function ensureMaterialIcons(){
if (!document.querySelector('link[href*="fonts.googleapis.com/icon"]')){
const link=document.createElement('link');
link.rel='stylesheet';
link.href='https://fonts.googleapis.com/icon?family=Material+Icons';
(document.head||document.documentElement).appendChild(link);
}
}
function injectStyles(){
if (document.getElementById(STYLE_ID)) return;
ensureMaterialIcons();
const css = [
'.oldyt-panel{width:101% !important;box-sizing:border-box;padding:6px 8px;min-height:120px;max-height:100%;display:flex;flex-direction:column;}',
'.oldyt-top-row{display:flex;align-items:center;gap:8px;margin-bottom:8px;min-height:32px;flex:0 0 auto;}',
'.oldyt-back{cursor:pointer;display:flex;align-items:center;gap:8px;font-weight:600;color:#fff;}',
'.oldyt-back .material-icons{font-size:18px;transform:translateY(1px)}',
'.oldyt-refresh-banner{margin-left:auto;background:#c62828;color:#fff;padding:6px 10px;border-radius:6px;display:flex;align-items:center;gap:8px;font-size:13px;}',
'.oldyt-refresh-banner.hidden{display:none !important;}',
'.oldyt-refresh-btn{background:transparent;border:1px solid rgba(255,255,255,0.2);color:#fff;padding:6px 8px;border-radius:4px;cursor:pointer;font-weight:600;}',
'.oldyt-list{display:flex;flex-direction:column;gap:6px;flex:1 1 auto;min-height:0;overflow-y:auto;overflow-x:hidden;padding-right:6px;-webkit-overflow-scrolling:touch;}',
'.oldyt-item{display:flex;align-items:center;gap:12px;padding:8px;border-radius:8px;min-height:52px;}',
'.oldyt-item:hover{background:rgba(255,255,255,0.03);transition:background .03s ease;}',
'.oldyt-icon{width:32px;height:32px;min-width:32px;display:flex;align-items:center;justify-content:center;border-radius:6px;background:rgba(255,255,255,0.03)}',
'.oldyt-icon img{width:18px;height:18px;}',
'.oldyt-icon .material-icons{font-size:18px;}',
'.oldyt-textcol{display:flex;flex-direction:column;gap:3px;flex:1 1 auto;min-width:0;}',
'.oldyt-name{color:#fff;font-size:13px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}',
'.oldyt-desc{color:rgba(255,255,255,0.78);font-size:12px;line-height:1;display:-webkit-box;-webkit-line-clamp:4;-webkit-box-orient:vertical;overflow:hidden;text-overflow:ellipsis;}',
'.oldyt-rightcol{margin-left:12px;display:flex;align-items:center;justify-content:flex-end;min-width:26.5px;}',
'.oldyt-rightcol.has-select{min-width:50px;}',
'.oldyt-toggle{display:inline-block;width:40px;height:22px;border-radius:22px;background:#6b6b6b;position:relative;box-shadow:inset 0 -2px 0 rgba(0,0,0,0.12);transition:background .12s ease;min-width:40px;}',
'.oldyt-toggle .oldyt-knob{position:absolute;top:3px;left:3px;width:16px;height:16px;border-radius:50%;background:#fff;box-shadow:0 1px 2px rgba(0,0,0,0.35);transition:left .12s ease;}',
'.oldyt-toggle.on{background:#e53935;}',
'.oldyt-toggle.on .oldyt-knob{left:21px;}',
'.oldyt-change-badge{display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px;border-radius:50%;background:#c62828;margin-left:8px;vertical-align:middle;flex:0 0 auto;}',
'.oldyt-change-badge .material-icons{font-size:12px;color:#fff;}',
'.oldyt-select{appearance:none;background:rgba(255,255,255,0.06);color:#fff;border:1px solid rgba(255,255,255,0.2);border-radius:6px;padding:4px 8px;font-size:12px;min-width:50px;cursor:pointer;}',
'.oldyt-select:focus{outline:none;}',
'.oldyt-list::-webkit-scrollbar{width:8px;height:8px;}',
'.oldyt-list::-webkit-scrollbar-thumb{background:rgba(255,255,255,0.06);border-radius:8px;}'
].join('\n');
const style=document.createElement('style'); style.id=STYLE_ID;
try{ style.appendChild(document.createTextNode(css)); }catch(_){ style.textContent=css; }
(document.head||document.documentElement).appendChild(style);
}
function makeMaterialIcon(name){
const i=document.createElement('i');
i.className='material-icons'; i.setAttribute('aria-hidden','true'); i.textContent=name;
return i;
}
/* ===================== PENDING / BADGE CALC ======================== */
function computePendingMap(){
const map={};
for (const cfg of getAllToggles()){
const cur=storageGet(cfg.id), appl=appliedGet(cfg.id);
const prompt = (typeof cfg.promptRefresh==='boolean') ? cfg.promptRefresh : true;
map[cfg.id] = prompt && (cur!==appl);
}
return map;
}
function anyPendingFromMap(m){ for (const k in m) if (m[k]) return true; return false; }
function computePendingMapForChildren(blockCfg){
const map={};
for(const cfg of (blockCfg.children||[])){
if (cfg.type==='select') { map[cfg.id]=false; continue; } // selects here don't require refresh
const cur=storageGet(cfg.id), appl=appliedGet(cfg.id);
const prompt=(typeof cfg.promptRefresh==='boolean')?cfg.promptRefresh:true;
map[cfg.id]=prompt && (cur!==appl);
}
return map;
}
/* ===================== INSIDE HELPERS (Safari-safe) ================= */
function isInsidePanel(panelEl, evt) {
try{
if (!panelEl || !evt) return false;
const t = evt.target;
if (t && panelEl.contains && panelEl.contains(t)) return true;
if (t && t.closest && t.closest('.oldyt-panel')) return true;
const p = (typeof evt.composedPath === 'function') ? evt.composedPath() : null;
if (p && Array.isArray(p) && p.indexOf(panelEl) !== -1) return true;
const r = panelEl.getBoundingClientRect && panelEl.getBoundingClientRect();
let x=0,y=0;
if (evt.touches && evt.touches[0]) { x=evt.touches[0].clientX; y=evt.touches[0].clientY; }
else if (evt.clientX!=null && evt.clientY!=null) { x=evt.clientX; y=evt.clientY; }
if (r && (x||y)) return (x>=r.left && x<=r.right && y>=r.top && y<=r.bottom);
}catch(_){}
return false;
}
/* ======================== BADGE (menu item) ======================== */
function createChangeBadge(){
const b=document.createElement('span'); b.className='oldyt-change-badge';
b.appendChild(makeMaterialIcon('autorenew')); return b;
}
function ensureMenuItemBadge(menuItem, contentDiv, show){
if(!menuItem || !contentDiv) return;
let badge = menuItem._oldytBadge;
if (show){
if(!badge){
badge=createChangeBadge();
contentDiv.insertBefore(badge, contentDiv.firstChild);
menuItem._oldytBadge=badge;
}
badge.style.display='inline-flex';
} else if (badge){
badge.style.display='none';
}
}
/* =================== PANEL / POPUP LIFECYCLE ======================= */
function buildSettingsBlockPanel(blockCfg, popup, panelMenu, parentPanel, menuItemRef, menuContentRef){
injectStyles();
const panel=document.createElement('div');
panel.className='ytp-panel oldyt-panel';
panel.setAttribute('role','menu');
// Top row with Back, Title, Refresh banner
const topRow=document.createElement('div'); topRow.className='oldyt-top-row';
const back=document.createElement('div'); back.className='oldyt-back'; back.setAttribute('role','button'); back.setAttribute('tabindex','0'); back.setAttribute('aria-label','Back');
back.appendChild(makeMaterialIcon('arrow_back'));
{ const label=document.createElement('div'); label.textContent='Back'; back.appendChild(label); }
topRow.appendChild(back);
const title=document.createElement('div'); title.className='oldyt-name'; title.textContent=blockCfg.name||'Settings';
topRow.appendChild(title);
const banner=document.createElement('div'); banner.className='oldyt-refresh-banner hidden'; banner.setAttribute('role','alert');
const bText=document.createElement('span'); bText.textContent='You must refresh now to apply changes.'; banner.appendChild(bText);
const btn = document.createElement('button'); btn.className='oldyt-refresh-btn';
const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
btn.textContent = isSafari ? 'Please Refresh' : 'Refresh now';
function robustRefreshNow(){
try{ for (const cfg of getAllToggles()) appliedSet(cfg.id, storageGet(cfg.id)); }catch(_){}
try{ ensureMenuItemBadge(menuItemRef, menuContentRef, false); }catch(_){}
try{ panel._detachOutsideHandlers && panel._detachOutsideHandlers(); }catch(_){}
const tries=[()=>location.reload(), ()=>{location.href=location.href;}, ()=>window.location.reload(), ()=>{window.top&&window.top.location&&window.top.location.reload();}, ()=>history.go(0)];
(function chain(i){ try{ tries[i](); }catch(_){ if(i+1<tries.length) setTimeout(()=>chain(i+1),30); } })(0);
}
btn.addEventListener('click', robustRefreshNow, {passive:true});
banner.appendChild(btn);
topRow.appendChild(banner);
panel.appendChild(topRow);
// === Version Labels ===
const version = 'v0.1'; // change as needed
const versionTop = document.createElement('div');
versionTop.textContent = version;
versionTop.style.position = 'absolute';
versionTop.style.top = '6px';
versionTop.style.right = '8px';
versionTop.style.fontSize = '11px';
versionTop.style.color = 'rgba(255,255,255,0.6)';
versionTop.style.fontWeight = '500';
versionTop.style.textShadow = '0 0 3px rgba(0,0,0,0.5)';
versionTop.style.pointerEvents = 'none';
versionTop.style.userSelect = 'none';
panel.appendChild(versionTop);
// List of child items
const list=document.createElement('div'); list.className='oldyt-list';
const frag=document.createDocumentFragment();
panel._pendingMap={};
for (const cfg of (blockCfg.children||[])){
const item=document.createElement('div'); item.className='oldyt-item';
const iconWrap=document.createElement('div'); iconWrap.className='oldyt-icon';
if(cfg.iconName) iconWrap.appendChild(makeMaterialIcon(cfg.iconName));
else if (cfg.iconUrl){ const img=document.createElement('img'); img.src=cfg.iconUrl; img.alt=cfg.name||''; iconWrap.appendChild(img); }
else iconWrap.appendChild(makeMaterialIcon('extension'));
item.appendChild(iconWrap);
const textcol=document.createElement('div'); textcol.className='oldyt-textcol';
const name=document.createElement('div'); name.className='oldyt-name'; name.textContent=cfg.name||'Unnamed';
const desc=document.createElement('div'); desc.className='oldyt-desc'; desc.textContent=cfg.desc||'';
textcol.appendChild(name); textcol.appendChild(desc); item.appendChild(textcol);
const rightcol=document.createElement('div'); rightcol.className='oldyt-rightcol';
// Render: toggle or dropdown
if (!cfg.type || cfg.type==='toggle'){
const toggle=document.createElement('div'); toggle.className='oldyt-toggle'; toggle.id='oldyt-toggle-'+cfg.id; toggle.setAttribute('role','switch'); toggle.setAttribute('tabindex','0');
const knob=document.createElement('div'); knob.className='oldyt-knob'; toggle.appendChild(knob);
rightcol.appendChild(toggle); item.appendChild(rightcol);
const cur=storageGet(cfg.id);
if(cur){ toggle.classList.add('on'); toggle.setAttribute('aria-checked','true'); } else toggle.setAttribute('aria-checked','false');
const handleToggle=()=>{
const nowOn = !toggle.classList.contains('on');
toggle.classList.toggle('on', nowOn);
toggle.setAttribute('aria-checked', nowOn ? 'true':'false');
storageSet(cfg.id, nowOn);
if (typeof cfg.onChange==='function'){ try{ cfg.onChange(nowOn, cfg.id); }catch(_){} }
const prompt = (typeof cfg.promptRefresh==='boolean') ? cfg.promptRefresh : true;
panel._pendingMap[cfg.id] = prompt && (nowOn !== appliedGet(cfg.id));
const localAny = anyPendingFromMap(panel._pendingMap);
const globalAny = anyPendingFromMap(computePendingMap());
panel._setRefreshVisible(localAny);
ensureMenuItemBadge(menuItemRef, menuContentRef, globalAny);
};
toggle.addEventListener('click', (e)=>{ e.stopPropagation(); handleToggle(); }, {passive:true});
toggle.addEventListener('keydown', (e)=>{ if(e.key==='Enter'||e.key===' '){ e.preventDefault(); e.stopPropagation(); handleToggle(); } }, {passive:false});
} else if (cfg.type==='select'){
rightcol.classList.add('has-select');
const sel = document.createElement('select');
sel.className = 'oldyt-select';
const curVal = storageGetVal(cfg.id, cfg.default);
for (const opt of (cfg.options||[])){
const o = document.createElement('option');
o.value = opt.value; o.textContent = opt.label;
if (opt.value === curVal) o.selected = true;
sel.appendChild(o);
}
sel.addEventListener('change', (e)=>{
const v = e.target.value;
storageSetVal(cfg.id, v);
try{ typeof cfg.onChange==='function' && cfg.onChange(v, cfg.id); }catch(_){}
// No refresh needed for this setting; keep banner state unchanged.
}, {passive:true});
rightcol.appendChild(sel);
item.appendChild(rightcol);
}
frag.appendChild(item);
}
list.appendChild(frag);
panel.appendChild(list);
panel._setRefreshVisible = (v)=>{ if(v) banner.classList.remove('hidden'); else banner.classList.add('hidden'); };
// init local pending state on open
panel._recalcPending = ()=>{
panel._pendingMap = computePendingMapForChildren(blockCfg);
panel._setRefreshVisible(anyPendingFromMap(panel._pendingMap));
};
panel._recalcPending();
function goBack(){
openNestedInPopup(popup, panelMenu, parentPanel);
ensureMenuItemBadge(menuItemRef, menuContentRef, anyPendingFromMap(computePendingMap()));
}
back.addEventListener('click', (e)=>{ e.preventDefault(); e.stopPropagation(); goBack(); }, {passive:false});
back.addEventListener('keydown', (e)=>{ if(e.key==='Enter'||e.key===' '){ e.preventDefault(); e.stopPropagation(); goBack(); } }, {passive:false});
// Outside-click behavior (return to parent panel)
panel._detachOutsideHandlers = null;
panel._attachOutsideHandlers = function attach() {
const panelEl = panel;
const onDown = (e) => { const inside = isInsidePanel(panelEl, e); if (!inside) goBack(); };
const onKeyDown = (e) => { if (e.key === 'Escape') goBack(); };
function detach(){ document.removeEventListener('pointerdown', onDown, true); document.removeEventListener('mousedown', onDown, true); document.removeEventListener('touchstart', onDown, true); document.removeEventListener('keydown', onKeyDown, true); }
if (window.PointerEvent) document.addEventListener('pointerdown', onDown, {capture:true, passive:true});
document.addEventListener('mousedown', onDown, {capture:true, passive:true});
document.addEventListener('touchstart', onDown, {capture:true, passive:true});
document.addEventListener('keydown', onKeyDown, {capture:true, passive:true});
panel._detachOutsideHandlers = detach;
};
return panel;
}
function buildNestedPanel(popup, panelMenu, menuItemRef, menuContentRef){
injectStyles();
const panel=document.createElement('div');
panel.className='ytp-panel oldyt-panel';
panel.setAttribute('role','menu');
// top row
const topRow=document.createElement('div'); topRow.className='oldyt-top-row';
const back=document.createElement('div'); back.className='oldyt-back'; back.setAttribute('role','button'); back.setAttribute('tabindex','0'); back.setAttribute('aria-label','Back to settings');
back.appendChild(makeMaterialIcon('arrow_back'));
{ const backLabel=document.createElement('div'); backLabel.textContent='Back'; back.appendChild(backLabel); }
topRow.appendChild(back);
// refresh banner (for refresh-required toggles)
const banner=document.createElement('div'); banner.className='oldyt-refresh-banner hidden'; banner.setAttribute('role','alert');
const bText=document.createElement('span'); bText.textContent='You must refresh now to apply changes'; banner.appendChild(bText);
const btn = document.createElement('button'); btn.className='oldyt-refresh-btn';
const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
btn.textContent = isSafari ? 'Please Refresh' : 'Refresh now';
function robustRefreshNow(){
try{ for (const cfg of getAllToggles()) appliedSet(cfg.id, storageGet(cfg.id)); }catch(_){}
try{ ensureMenuItemBadge(menuItemRef, menuContentRef, false); }catch(_){}
try{ panel._detachOutsideHandlers && panel._detachOutsideHandlers(); }catch(_){}
const tries=[()=>location.reload(), ()=>{location.href=location.href;}, ()=>window.location.reload(), ()=>{window.top&&window.top.location&&window.top.location.reload();}, ()=>history.go(0)];
(function chain(i){ try{ tries[i](); }catch(_){ if(i+1<tries.length) setTimeout(()=>chain(i+1),30); } })(0);
}
btn.addEventListener('click', robustRefreshNow, {passive:true});
banner.appendChild(btn);
topRow.appendChild(banner);
panel.appendChild(topRow);
// === Version Labels ===
const version = 'v0.1';
const versionTop = document.createElement('div');
versionTop.textContent = version;
versionTop.style.position = 'absolute';
versionTop.style.top = '6px';
versionTop.style.right = '8px';
versionTop.style.fontSize = '11px';
versionTop.style.color = 'rgba(255,255,255,0.6)';
versionTop.style.fontWeight = '500';
versionTop.style.textShadow = '0 0 3px rgba(0,0,0,0.5)';
versionTop.style.pointerEvents = 'none';
versionTop.style.userSelect = 'none';
panel.appendChild(versionTop);
// list (root toggles + blocks)
const list=document.createElement('div'); list.className='oldyt-list';
const frag=document.createDocumentFragment();
panel._pendingMap={};
// Root toggles
for (const cfg of CONFIG_TOGGLES){
const item=document.createElement('div'); item.className='oldyt-item';
const iconWrap=document.createElement('div'); iconWrap.className='oldyt-icon';
if(cfg.iconName) iconWrap.appendChild(makeMaterialIcon(cfg.iconName));
else if (cfg.iconUrl){ const img=document.createElement('img'); img.src=cfg.iconUrl; img.alt=cfg.name||''; iconWrap.appendChild(img); }
else iconWrap.appendChild(makeMaterialIcon('extension'));
item.appendChild(iconWrap);
const textcol=document.createElement('div'); textcol.className='oldyt-textcol';
const name=document.createElement('div'); name.className='oldyt-name'; name.textContent=cfg.name||'Unnamed';
const desc=document.createElement('div'); desc.className='oldyt-desc'; desc.textContent=cfg.desc||'';
textcol.appendChild(name); textcol.appendChild(desc); item.appendChild(textcol);
const rightcol=document.createElement('div'); rightcol.className='oldyt-rightcol';
const toggle=document.createElement('div'); toggle.className='oldyt-toggle'; toggle.id='oldyt-toggle-'+cfg.id; toggle.setAttribute('role','switch'); toggle.setAttribute('tabindex','0');
const knob=document.createElement('div'); knob.className='oldyt-knob'; toggle.appendChild(knob);
rightcol.appendChild(toggle); item.appendChild(rightcol);
const cur=storageGet(cfg.id);
if(cur){ toggle.classList.add('on'); toggle.setAttribute('aria-checked','true'); } else toggle.setAttribute('aria-checked','false');
const handleToggle=()=>{
const nowOn = !toggle.classList.contains('on');
toggle.classList.toggle('on', nowOn);
toggle.setAttribute('aria-checked', nowOn ? 'true':'false');
storageSet(cfg.id, nowOn);
if (typeof cfg.onChange==='function'){ try{ cfg.onChange(nowOn, cfg.id); }catch(_){} }
const prompt = (typeof cfg.promptRefresh==='boolean') ? cfg.promptRefresh : true;
panel._pendingMap[cfg.id] = prompt && (nowOn !== appliedGet(cfg.id));
const any = anyPendingFromMap(panel._pendingMap);
panel._setRefreshVisible(any);
ensureMenuItemBadge(menuItemRef, menuContentRef, any);
};
toggle.addEventListener('click', (e)=>{ e.stopPropagation(); handleToggle(); }, {passive:true});
toggle.addEventListener('keydown', (e)=>{ if(e.key==='Enter'||e.key===' '){ e.preventDefault(); e.stopPropagation(); handleToggle(); } }, {passive:false});
frag.appendChild(item);
}
// Setting blocks (open nested sub-panel)
for (const block of CONFIG_BLOCKS){
const item=document.createElement('div'); item.className='oldyt-item';
const iconWrap=document.createElement('div'); iconWrap.className='oldyt-icon';
if (block.iconName) iconWrap.appendChild(makeMaterialIcon(block.iconName)); else iconWrap.appendChild(makeMaterialIcon('folder'));
item.appendChild(iconWrap);
const textcol=document.createElement('div'); textcol.className='oldyt-textcol';
const name=document.createElement('div'); name.className='oldyt-name'; name.textContent=block.name||'Settings';
const desc=document.createElement('div'); desc.className='oldyt-desc'; desc.textContent=block.desc||'';
textcol.appendChild(name); textcol.appendChild(desc); item.appendChild(textcol);
const rightcol=document.createElement('div'); rightcol.className='oldyt-rightcol';
const arrow=document.createElement('div'); arrow.appendChild(makeMaterialIcon('chevron_right'));
rightcol.appendChild(arrow); item.appendChild(rightcol);
const openBlock = (ev)=>{
if (ev){
ev.preventDefault && ev.preventDefault();
ev.stopPropagation && ev.stopPropagation();
ev.stopImmediatePropagation && ev.stopImmediatePropagation();
}
panel._detachOutsideHandlers && panel._detachOutsideHandlers();
const blockPanel = buildSettingsBlockPanel(block, popup, panelMenu, panel, menuItemRef, menuContentRef);
setTimeout(()=>{
openNestedInPopup(popup, panelMenu, blockPanel);
try { blockPanel.setAttribute('tabindex','-1'); blockPanel.focus({preventScroll:true}); } catch(_) {}
}, 0);
};
item.addEventListener('pointerdown', (e)=>{ e.preventDefault(); e.stopPropagation(); e.stopImmediatePropagation(); }, {capture:true});
item.addEventListener('click', openBlock, {capture:true});
item.addEventListener('keydown', (e)=>{ if(e.key==='Enter'||e.key===' '){ e.preventDefault(); openBlock(e); } });
frag.appendChild(item);
}
list.appendChild(frag);
panel.appendChild(list);
panel._setRefreshVisible = (v)=>{ if(v) banner.classList.remove('hidden'); else banner.classList.add('hidden'); };
// ===== Back behavior (to YT root settings menu)
function doBack(){
const any = anyPendingFromMap(panel._pendingMap);
restorePanelFromPopup(popup, panel);
ensureMenuItemBadge(menuItemRef, menuContentRef, any);
}
back.addEventListener('click', (e) => { e.preventDefault(); e.stopPropagation(); doBack(); }, {passive:false});
back.addEventListener('keydown', (e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); e.stopPropagation(); doBack(); } }, {passive:false});
// OUTSIDE = BACK
panel._detachOutsideHandlers = null;
panel._attachOutsideHandlers = function attach() {
const popupEl = popup;
const panelEl = panel;
const onDown = (e) => {
const insidePanel = isInsidePanel(panelEl, e);
const insidePopup = isInsidePanel(popupEl, e);
if (insidePanel) return;
if (insidePopup) { doBack(); } else { doBack(); }
};
const onFocusIn = (e) => {
const insidePanel = isInsidePanel(panelEl, e);
const insidePopup = isInsidePanel(popupEl, e);
if (insidePanel) return;
if (insidePopup) { doBack(); } else { doBack(); }
};
const onKeyDown = (e) => { if (e.key === 'Escape') doBack(); };
function detach() {
const cap = true;
if (window.PointerEvent) document.removeEventListener('pointerdown', onDown, cap);
document.removeEventListener('mousedown', onDown, cap);
document.removeEventListener('touchstart', onDown, cap);
document.removeEventListener('focusin', onFocusIn, cap);
document.removeEventListener('keydown', onKeyDown, cap);
}
const cap = true;
if (window.PointerEvent) document.addEventListener('pointerdown', onDown, {capture:cap, passive:true});
document.addEventListener('mousedown', onDown, {capture:cap, passive:true});
document.addEventListener('touchstart', onDown, {capture:cap, passive:true});
document.addEventListener('focusin', onFocusIn, cap);
document.addEventListener('keydown', onKeyDown, {capture:cap, passive:true});
panel._detachOutsideHandlers = detach;
};
// init refresh visibility
panel._pendingMap = computePendingMap();
panel._setRefreshVisible(anyPendingFromMap(panel._pendingMap));
return panel;
}
function injectIntoPopup(popup){
try{
if(!popup || !(popup instanceof HTMLElement)) return;
const panelMenu = popup.querySelector('.ytp-panel-menu') || popup.querySelector('.ytp-panel');
if(!panelMenu) return;
if(panelMenu.querySelector('.oldyt-menuitem')) return;
injectStyles();
const menuItem=document.createElement('div'); menuItem.className='ytp-menuitem oldyt-menuitem';
menuItem.setAttribute('role','menuitem'); menuItem.setAttribute('tabindex','0'); menuItem.setAttribute('aria-haspopup','true');
const iconDiv=document.createElement('div'); iconDiv.className='ytp-menuitem-icon';
iconDiv.appendChild(makeMaterialIcon('settings')); menuItem.appendChild(iconDiv);
const labelDiv=document.createElement('div'); labelDiv.className='ytp-menuitem-label'; labelDiv.textContent='OldYTPlayer'; menuItem.appendChild(labelDiv);
const contentDiv=document.createElement('div'); contentDiv.className='ytp-menuitem-content';
const arrow=document.createElement('div'); arrow.style.opacity='0.9'; arrow.textContent='Tweak settings here';
contentDiv.appendChild(arrow); menuItem.appendChild(contentDiv);
panelMenu.insertBefore(menuItem, panelMenu.firstChild || null);
const nestedPanel = buildNestedPanel(popup, panelMenu, menuItem, contentDiv);
const openHandler = (ev)=>{
if (ev){ ev.preventDefault && ev.preventDefault(); ev.stopPropagation && ev.stopPropagation(); }
nestedPanel._pendingMap = computePendingMap();
nestedPanel._setRefreshVisible(anyPendingFromMap(nestedPanel._pendingMap));
ensureMenuItemBadge(menuItem, contentDiv, anyPendingFromMap(nestedPanel._pendingMap));
openNestedInPopup(popup, panelMenu, nestedPanel);
ensureMenuItemBadge(menuItem, contentDiv, false);
nestedPanel._attachOutsideHandlers && nestedPanel._attachOutsideHandlers();
};
menuItem.addEventListener('click', openHandler, {passive:false});
menuItem.addEventListener('keydown', (e)=>{ if(e.key==='Enter'||e.key===' '){ e.preventDefault(); openHandler(e); } }, {passive:false});
const popupObserver = new MutationObserver(()=>{
try{
if(!document.contains(popup) || (popup.style && popup.style.display==='none')){
safeRestorePanel(panelMenu);
const pend = computePendingMap(); ensureMenuItemBadge(menuItem, contentDiv, anyPendingFromMap(pend));
popupObserver.disconnect();
}
}catch(_){}
});
popupObserver.observe(popup, { attributes:true, childList:true, subtree:false });
const menuObserver = new MutationObserver(()=>{
if(!panelMenu.contains(menuItem)){ menuObserver.disconnect(); setTimeout(()=>injectIntoPopup(popup), 120); }
});
menuObserver.observe(panelMenu, { childList:true, subtree:false });
panelMenu._oldytInjected = { menuItem, nestedPanel, popupObserver, menuObserver };
}catch(_) {}
}
function openNestedInPopup(_popup, panelMenu, newPanel){
try{
const current = panelMenu.querySelector('.oldyt-panel');
if (current && current !== newPanel){
if (current._detachOutsideHandlers) { try{ current._detachOutsideHandlers(); }catch(_){} }
try{ panelMenu.removeChild(current); }catch(_){}
}
Array.from(panelMenu.children).forEach(ch => {
if (ch !== newPanel) { try { ch.style.display = 'none'; } catch(_){} }
});
if (!panelMenu.contains(newPanel)) panelMenu.appendChild(newPanel);
panelMenu._oldytOpen = true;
newPanel._attachOutsideHandlers && newPanel._attachOutsideHandlers();
}catch(_){}
}
function restorePanelFromPopup(popup, _nestedPanel){
const panelMenu = popup.querySelector('.ytp-panel-menu') || popup.querySelector('.ytp-panel');
if(!panelMenu) return;
safeRestorePanel(panelMenu);
}
function safeRestorePanel(panelMenu){
if(!panelMenu) return;
const nested = panelMenu.querySelector('.oldyt-panel');
if (nested){
if (nested._detachOutsideHandlers) { try{ nested._detachOutsideHandlers(); }catch(_){} }
try{ panelMenu.removeChild(nested); }catch(_) {}
}
const ch = panelMenu.children;
for (let i=0;i<ch.length;i++){ try{ ch[i].style.display=''; }catch(_){} }
panelMenu._oldytOpen = false;
}
/* ==================== GLOBAL INJECTION OBSERVER ===================== */
const processedPopups = new WeakSet();
function scanAndInjectAll(){
injectStyles();
const list = document.querySelectorAll('.ytp-popup.ytp-settings-menu');
for (let i=0;i<list.length;i++){
const p = list[i];
if (!processedPopups.has(p)) {
injectIntoPopup(p);
processedPopups.add(p);
}
}
}
function startObserver(){
setTimeout(scanAndInjectAll, 300);
const mo=new MutationObserver((muts)=>{
for (let i=0;i<muts.length;i++){
const m = muts[i];
for (let j=0;j<m.addedNodes.length;j++){
const n = m.addedNodes[j];
if(!(n && n.nodeType===1)) continue;
const el = n;
if (el.matches && el.matches('.ytp-popup.ytp-settings-menu')) {
if (!processedPopups.has(el)) { injectIntoPopup(el); processedPopups.add(el); }
} else if (el.querySelector) {
const found = el.querySelectorAll('.ytp-popup.ytp-settings-menu');
for (let k=0;k<found.length;k++){
const p = found[k];
if (!processedPopups.has(p)) { injectIntoPopup(p); processedPopups.add(p); }
}
}
}
}
});
mo.observe(document.documentElement, { childList:true, subtree:true });
setInterval(scanAndInjectAll, 3000);
}
startObserver();
// Intro Function -- Experimental, I'm not sure I will keep it in later versions.
(function() {
const LS_KEY = 'oldytp_firstTime';
if (localStorage.getItem(LS_KEY)) return; // already done
function waitForElement(selector, timeout = 10000) {
return new Promise(resolve => {
const tryStart = () => {
const el = document.querySelector(selector);
if (el) return resolve(el);
if (!document.body) return requestAnimationFrame(tryStart);
const obs = new MutationObserver(() => {
const found = document.querySelector(selector);
if (found) { obs.disconnect(); resolve(found); }
});
obs.observe(document.body, { childList: true, subtree: true });
setTimeout(() => { obs.disconnect(); resolve(null); }, timeout);
};
tryStart();
});
}
async function runIntro() {
const settingsBtn = await waitForElement('.ytp-settings-button');
if (!settingsBtn) return;
// === Magnificent PS5-style glow ===
const glow = document.createElement('div');
glow.style.cssText = `
position: fixed; /* fixed instead of absolute */
border-radius: 50%;
pointer-events: none;
z-index: 999998;
background: radial-gradient(circle, rgba(255,255,255,0.35) 0%, rgba(0,186,255,0.2) 40%, rgba(0,186,255,0) 70%);
filter: blur(12px);
transform: scale(1);
animation: ps5Glow 1.4s infinite alternate ease-in-out;
`;
document.body.appendChild(glow);
const style = document.createElement('style');
style.textContent = `
@keyframes ps5Glow {
0% { transform: scale(0.85); opacity: 0.7; }
50% { transform: scale(1.1); opacity: 1; }
100% { transform: scale(0.95); opacity: 0.8; }
}
`;
document.head.appendChild(style);
// Lightweight dynamic positioning
let stopAnimation = false;
function updateGlow() {
if (stopAnimation) return;
const rect = settingsBtn.getBoundingClientRect();
const size = Math.max(rect.width, rect.height) * 2; // big halo
glow.style.left = rect.left + rect.width / 2 - size / 2 + 'px';
glow.style.top = rect.top + rect.height / 2 - size / 2 + 'px';
glow.style.width = glow.style.height = size + 'px';
requestAnimationFrame(updateGlow);
}
updateGlow();
settingsBtn.addEventListener('click', () => {
stopAnimation = true;
glow.remove();
style.remove();
localStorage.setItem(LS_KEY, 'true'); // mark intro as done
}, { once: true });
}
runIntro();
})();
/* =================================================================== */
} catch(err){ console.error('[OldYTPlayer] top-level error', err); }
})();
/*
Credits go to "Control Panel for Youtube" for finding this: https://github.com/insin/control-panel-for-youtube/
More information on features are on the main page.
You can use this code in your own projects, if you would like.
If you are reading, please give a good feedback on my page, as I update regularly.
*/