Force YouTube to show compact grid (max 6 videos per row) rather than "slim" grid (max 3 videos per row)
La data de
// ==UserScript==
// @name YouTube - Force Compact Grid (increases max # videos per row)
// @namespace https://gist.github.com/lbmaian/8c6961584c0aebf41ee7496609f60bc3
// @version 0.1
// @description Force YouTube to show compact grid (max 6 videos per row) rather than "slim" grid (max 3 videos per row)
// @author lbmaian
// @match https://www.youtube.com/*
// @exclude https://www.youtube.com/embed/*
// @icon https://www.youtube.com/favicon.ico
// @run-at document-start
// @grant none
// ==/UserScript==
(function() {
'use strict';
const DEBUG = false;
const logContext = '[YouTube - Force Compact Grid]';
var debug;
if (DEBUG) {
debug = function(...args) {
console.debug(logContext, ...args);
};
} else {
debug = function() {};
}
function log(...args) {
console.log(logContext, ...args);
}
function info(...args) {
console.info(logContext, ...args);
}
function warn(...args) {
console.warn(logContext, ...args);
}
function error(...args) {
console.error(logContext, ...args);
}
function updateResponseData(response, label) {
const tabs = response?.contents?.twoColumnBrowseResultsRenderer?.tabs;
debug(label, 'contents.twoColumnBrowseResultsRenderer.tabs', tabs);
if (tabs) {
for (const tab of tabs) {
const tabRenderer = tab.tabRenderer;
if (tabRenderer) {
const richGridRenderer = tabRenderer.content?.richGridRenderer;
if (richGridRenderer && richGridRenderer.style == 'RICH_GRID_STYLE_SLIM') {
log(label, 'tab', tabRenderer.title, 'tabRenderer.content.richGridRenderer.style:', richGridRenderer.style, '=> RICH_GRID_STYLE_COMPACT');
richGridRenderer.style = 'RICH_GRID_STYLE_COMPACT';
}
}
}
}
}
// Note: Both of the following event listeners are too late:
// ytd-app's own yt-page-data-fetched event listener (onYtPageDataFetched) already fires
// by the time our own yt-page-data-fetched event listener fires,
// and yt-page-data-fetched fires before yt-navigate-finish fires
// document.addEventListener('yt-page-data-fetched', evt => {
// debug('Navigated to', evt.detail.pageData.url);
// debug(evt);
// updateResponseData(evt.detail.pageData.response, 'yt-page-data-fetched pageData.response');
// });
// document.addEventListener('yt-navigate-finish', evt => {
// debug('Navigated to', evt.detail.response.url);
// debug(evt);
// updateResponseData(evt.detail.response.response, 'yt-navigate-finish response.response');
// });
document.addEventListener('DOMContentLoaded', evt => {
// Handle the initial page
debug('ytInitialData', window.ytInitialData);
updateResponseData(window.ytInitialData, 'ytInitialData');
// Handle changing tabs (e.g. 'videos' or 'live' tab)
// Need to hook into ytd-app's ytd-app's own yt-page-data-fetched event listener (onYtPageDataFetched),
// so that we can modify the data before that event listener fires
const ytdApp = document.getElementsByTagName('ytd-app')[0];
debug('ytd-app', ytdApp);
if (!ytdApp) {
error('unexpectedly could not find ytd-app after page load');
return;
}
const origOnYtPageDataFetched = ytdApp.onYtPageDataFetched;
ytdApp.onYtPageDataFetched = function(evt, detail) {
debug('Navigated to', detail.pageData.url);
debug(evt);
updateResponseData(evt.detail.pageData.response, 'yt-page-data-fetched pageData.response');
return origOnYtPageDataFetched.call(this, evt, detail);
};
});
})();