Skip to content

Instantly share code, notes, and snippets.

@kiranwayne
Created December 1, 2025 04:55
Show Gist options
  • Select an option

  • Save kiranwayne/f85cb0e7735e1051d6e74536c5a017f3 to your computer and use it in GitHub Desktop.

Select an option

Save kiranwayne/f85cb0e7735e1051d6e74536c5a017f3 to your computer and use it in GitHub Desktop.
// ==UserScript==
// @name GitHub Enhanced
// @namespace http://tampermonkey.net/
// @version 1.8.0
// @description Customize content width on GitHub pages with a slider. Dark mode panel & improved input behavior.
// @author kiranwayne
// @match https://github.com/*
// @updateURL https://gist.github.com/kiranwayne/f85cb0e7735e1051d6e74536c5a017f3/raw/github_enhanced.js
// @downloadURL https://gist.github.com/kiranwayne/f85cb0e7735e1051d6e74536c5a017f3/raw/github_enhanced.js
// @match https://gist.github.com/*
// @grant GM_getValue
// @grant GM_setValue
// @grant GM_registerMenuCommand
// @grant GM_unregisterMenuCommand
// @run-at document-end
// ==/UserScript==
(async () => {
'use strict';
// --- Configuration & Constants ---
const SCRIPT_NAME = 'GitHub Enhanced';
const SCRIPT_VERSION = '1.8.0';
const SCRIPT_AUTHOR = 'kiranwayne';
const CONFIG_PREFIX = 'githubEnhancedWidth_v1_';
const MAX_WIDTH_PX_KEY = CONFIG_PREFIX + 'maxWidthPx';
const USE_DEFAULT_WIDTH_KEY = CONFIG_PREFIX + 'useDefaultWidth';
const UI_VISIBLE_KEY = CONFIG_PREFIX + 'uiVisible';
const WIDTH_STYLE_ID = 'gh-enhanced-width-style';
const LAYOUT_ADJUSTMENTS_STYLE_ID = 'gh-enhanced-layout-adjustments-style';
const GLOBAL_STYLE_ID = 'gh-enhanced-global-style';
const PRELOAD_STYLE_ID = 'gh-enhanced-preload-hide-style';
const SETTINGS_PANEL_ID = 'gh-userscript-settings-panel';
// CSS selector for elements whose max-width will be controlled by the script
const WIDTH_TARGET_SELECTOR = `
.application-main .container-xl,
.application-main .container-lg,
.container-xl,
.container-lg,
.feed-content > .Details > .container-lg,
.application-main div[data-target="react-app.reactRoot"] div[class^='prc-PageLayout-Content-'] > div[class^='Box-sc-'],
.application-main div[data-target="react-app.reactRoot"] > div[class^='Box-sc-'] > div[class^='Box-sc-'] > div[class^='Box-sc-'] > div[class^='Box-sc-'],
.application-main div[data-target="react-app.reactRoot"] div[class^='IssueCreatePage-module__createPaneContainer-'],
.application-main div[style^="--sticky-pane-height:"] > div[class^='Box-sc-'] > div[class^='Box-sc-'] > div[class^='Box-sc-'] > div[class^='Box-sc-']:nth-child(2) > div[class^='Box-sc-'],
#js-repo-pjax-container div[style^="--sticky-pane-height:"] > div[class^='Box-sc-']:first-child,
.gist-content .container-lg
`.split(',').map(s => s.trim()).filter(s => s).join(', ');
// Original GitHub constraints maintained
const SCRIPT_DEFAULT_CUSTOM_WIDTH_PX = 1600;
const MIN_WIDTH_PX = 1500;
const MAX_WIDTH_PX = 3300;
const STEP_WIDTH_PX = 20;
let config = {
maxWidthPx: SCRIPT_DEFAULT_CUSTOM_WIDTH_PX,
useDefaultWidth: true,
uiVisible: false,
};
let settingsPanel = null, widthSlider = null, widthLabel = null, widthInput = null;
let defaultWidthCheckbox = null;
let menuCommandId_ToggleUI = null;
const allStyleRoots = new Set();
// --- Helper Functions ---
async function loadSettings() {
config.useDefaultWidth = await GM_getValue(USE_DEFAULT_WIDTH_KEY, true);
config.maxWidthPx = await GM_getValue(MAX_WIDTH_PX_KEY, SCRIPT_DEFAULT_CUSTOM_WIDTH_PX);
config.maxWidthPx = Math.max(MIN_WIDTH_PX, Math.min(MAX_WIDTH_PX, config.maxWidthPx)); // Clamp
config.uiVisible = await GM_getValue(UI_VISIBLE_KEY, false);
}
async function saveSetting(key, value) {
if (key === MAX_WIDTH_PX_KEY) {
const numValue = parseInt(value, 10);
if (!isNaN(numValue)) {
const clampedValue = Math.max(MIN_WIDTH_PX, Math.min(MAX_WIDTH_PX, numValue));
await GM_setValue(key, clampedValue);
config.maxWidthPx = clampedValue;
} else { return; }
} else {
await GM_setValue(key, value);
if (key === USE_DEFAULT_WIDTH_KEY) config.useDefaultWidth = value;
else if (key === UI_VISIBLE_KEY) config.uiVisible = value;
}
}
// --- Style Generation Functions ---
function getCustomWidthConstraintCss() {
if (config.useDefaultWidth) return '';
return `${WIDTH_TARGET_SELECTOR} { max-width: ${config.maxWidthPx}px !important; margin-left: auto !important; margin-right: auto !important; }`;
}
function getLayoutAdjustmentsCss() {
if (config.useDefaultWidth) return '';
return `
.react-repos-overview-margin { margin-right: 0 !important; }
.application-main .col-11 { width: 100% !important; }
#js-repo-pjax-container .js-issue-row .text-right { max-width: 303px !important; }
`;
}
function getGlobalPanelCss() {
// Dark Mode CSS (Ported from Gemini Script)
return `
#${SETTINGS_PANEL_ID} {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
font-size: 13px;
line-height: 1.4;
position: fixed;
top: 20px;
right: 20px;
z-index: 99999;
background-color: #1e1f20; /* Dark Grey */
color: #e3e3e3;
border: 1px solid #444746;
border-radius: 8px;
padding: 14px;
box-shadow: 0 4px 24px rgba(0,0,0,0.5);
min-width: 250px;
display: flex;
flex-direction: column;
gap: 4px;
}
#${SETTINGS_PANEL_ID} h4 {
margin: 0 0 8px 0;
font-size: 15px;
font-weight: 600;
color: #e3e3e3;
padding-bottom: 6px;
border-bottom: 1px solid #444746;
display: flex;
justify-content: space-between;
align-items: center;
}
#${SETTINGS_PANEL_ID} .close-btn {
cursor: pointer;
font-size: 20px;
color: #8e918f;
line-height: 1;
font-weight: normal;
}
#${SETTINGS_PANEL_ID} .close-btn:hover { color: #fff; }
#${SETTINGS_PANEL_ID} .meta-info {
margin: 0;
font-size: 11px;
color: #c4c7c5;
opacity: 0.8;
line-height: 1.3;
}
#${SETTINGS_PANEL_ID} .control-group { margin-top: 10px; }
#${SETTINGS_PANEL_ID} label {
cursor: pointer;
display: flex;
align-items: center;
color: #e3e3e3;
margin-bottom: 8px;
}
#${SETTINGS_PANEL_ID} input[type="checkbox"] {
margin-right: 8px;
accent-color: #8ab4f8;
width: 14px; height: 14px;
}
#${SETTINGS_PANEL_ID} .width-controls-wrapper {
display: flex;
align-items: center;
gap: 8px;
}
#${SETTINGS_PANEL_ID} input[type="range"] {
flex-grow: 1;
accent-color: #8ab4f8;
background: #444746;
height: 4px;
border-radius: 2px;
cursor: pointer;
}
#${SETTINGS_PANEL_ID} input[type="number"] {
width: 55px;
padding: 4px 6px;
background-color: #2a2b2d;
color: #e3e3e3;
border: 1px solid #444746;
border-radius: 6px;
text-align: left;
font-family: monospace;
font-size: 12px;
}
#${SETTINGS_PANEL_ID} input[type="number"]:focus { outline: 2px solid #8ab4f8; border-color: transparent; }
#${SETTINGS_PANEL_ID} .width-value-label {
min-width: 45px;
text-align: left;
font-family: monospace;
color: #e3e3e3;
font-size: 12px;
}
#${SETTINGS_PANEL_ID} input:disabled,
#${SETTINGS_PANEL_ID} .width-value-label.disabled {
opacity: 0.5;
cursor: not-allowed;
}
`;
}
// --- Style Injection / Update / Removal Functions ---
function injectOrUpdateStyle(root, styleId, cssContent) {
if (!root) return;
let style = root.querySelector(`#${styleId}`);
if (cssContent && cssContent.trim() !== '') {
if (!style) {
style = document.createElement('style'); style.id = styleId; style.textContent = cssContent;
if (root === document.head || (root.nodeType === Node.ELEMENT_NODE && root.shadowRoot === null) || root.nodeType === Node.DOCUMENT_FRAGMENT_NODE) root.appendChild(style);
else if (root.shadowRoot) root.shadowRoot.appendChild(style);
} else if (style.textContent !== cssContent) {
style.textContent = cssContent;
}
} else {
if (style) style.remove();
}
}
function applyGlobalHeadStyles() {
if (document.head) injectOrUpdateStyle(document.head, GLOBAL_STYLE_ID, getGlobalPanelCss());
}
function applyCustomWidthConstraintStyleToAllRoots() {
const css = getCustomWidthConstraintCss();
allStyleRoots.forEach(r => { if(r) injectOrUpdateStyle(r, WIDTH_STYLE_ID, css); });
}
function applyLayoutAdjustmentsStyleToAllRoots() {
const css = getLayoutAdjustmentsCss();
allStyleRoots.forEach(r => { if(r) injectOrUpdateStyle(r, LAYOUT_ADJUSTMENTS_STYLE_ID, css); });
}
// --- UI State Update ---
function updateUIState() {
if (settingsPanel && defaultWidthCheckbox && widthSlider && widthLabel && widthInput) {
defaultWidthCheckbox.checked = config.useDefaultWidth;
const isCustomWidthEnabled = !config.useDefaultWidth;
[widthSlider, widthInput].forEach(el => el.disabled = !isCustomWidthEnabled);
const opacityValue = isCustomWidthEnabled ? 1 : 0.5;
widthSlider.style.opacity = opacityValue;
widthInput.style.opacity = opacityValue;
widthLabel.style.opacity = opacityValue;
widthSlider.value = config.maxWidthPx;
widthInput.value = config.maxWidthPx;
widthLabel.textContent = `${config.maxWidthPx}px`;
}
}
async function closePanel() {
await saveSetting(UI_VISIBLE_KEY, false);
removeSettingsUI();
updateTampermonkeyMenu();
}
function removeSettingsUI() {
settingsPanel = document.getElementById(SETTINGS_PANEL_ID);
if (settingsPanel) {
settingsPanel.remove();
settingsPanel = null; widthSlider = null; widthLabel = null; widthInput = null; defaultWidthCheckbox = null;
}
}
function createSettingsUI() {
if (document.getElementById(SETTINGS_PANEL_ID) || !config.uiVisible) return;
if (!document.body) return;
settingsPanel = document.createElement('div'); settingsPanel.id = SETTINGS_PANEL_ID;
// Header
const header = document.createElement('h4');
const titleSpan = document.createElement('span'); titleSpan.textContent = SCRIPT_NAME;
const closeBtn = document.createElement('span'); closeBtn.className = 'close-btn'; closeBtn.textContent = '×'; closeBtn.onclick = closePanel;
header.append(titleSpan, closeBtn);
// Meta Info
const versionP = document.createElement('p'); versionP.className = 'meta-info'; versionP.textContent = `Version: ${SCRIPT_VERSION}`;
const authorP = document.createElement('p'); authorP.className = 'meta-info'; authorP.textContent = `Author: ${SCRIPT_AUTHOR}`;
// Controls
const controlContainer = document.createElement('div'); controlContainer.className = 'control-group';
const checkboxWrapper = document.createElement('div');
defaultWidthCheckbox = document.createElement('input'); defaultWidthCheckbox.type = 'checkbox'; defaultWidthCheckbox.id = 'gh-userscript-defaultwidth-toggle';
const defaultWidthLabelElement = document.createElement('label'); defaultWidthLabelElement.htmlFor = 'gh-userscript-defaultwidth-toggle';
defaultWidthLabelElement.append(defaultWidthCheckbox, document.createTextNode(' Use GitHub Default Width'));
checkboxWrapper.appendChild(defaultWidthLabelElement);
const sliderWrapper = document.createElement('div'); sliderWrapper.className = 'width-controls-wrapper';
widthLabel = document.createElement('span'); widthLabel.className = 'width-value-label';
widthSlider = document.createElement('input'); widthSlider.type = 'range'; widthSlider.min = MIN_WIDTH_PX; widthSlider.max = MAX_WIDTH_PX; widthSlider.step = STEP_WIDTH_PX;
widthInput = document.createElement('input'); widthInput.type = 'number'; widthInput.min = MIN_WIDTH_PX; widthInput.max = MAX_WIDTH_PX; widthInput.step = STEP_WIDTH_PX;
sliderWrapper.append(widthLabel, widthSlider, widthInput);
controlContainer.append(checkboxWrapper, sliderWrapper);
settingsPanel.append(header, versionP, authorP, controlContainer);
document.body.appendChild(settingsPanel);
// Events
defaultWidthCheckbox.addEventListener('change', async (e) => {
await saveSetting(USE_DEFAULT_WIDTH_KEY, e.target.checked);
applyCustomWidthConstraintStyleToAllRoots();
applyLayoutAdjustmentsStyleToAllRoots();
updateUIState();
});
// Slider - Instant Update
widthSlider.addEventListener('input', (e) => {
const nw = parseInt(e.target.value, 10);
config.maxWidthPx = nw;
widthLabel.textContent = `${nw}px`;
widthInput.value = nw;
if (!config.useDefaultWidth) applyCustomWidthConstraintStyleToAllRoots();
});
widthSlider.addEventListener('change', async (e) => {
await saveSetting(MAX_WIDTH_PX_KEY, parseInt(e.target.value, 10));
});
// Input - Commit on Change/Enter
const commitInputValue = async () => {
let val = parseInt(widthInput.value, 10);
if (isNaN(val)) { widthInput.value = config.maxWidthPx; return; }
// Clamp
val = Math.max(MIN_WIDTH_PX, Math.min(MAX_WIDTH_PX, val));
config.maxWidthPx = val;
widthInput.value = val;
widthSlider.value = val;
widthLabel.textContent = `${val}px`;
await saveSetting(MAX_WIDTH_PX_KEY, val);
if (!config.useDefaultWidth) applyCustomWidthConstraintStyleToAllRoots();
};
widthInput.addEventListener('change', commitInputValue);
widthInput.addEventListener('keydown', (e) => {
if (e.key === 'Enter') widthInput.blur();
});
updateUIState();
applyGlobalHeadStyles();
}
function updateTampermonkeyMenu() {
if (menuCommandId_ToggleUI !== null && typeof GM_unregisterMenuCommand === 'function') {
try { GM_unregisterMenuCommand(menuCommandId_ToggleUI); } catch (e) { /* ignore */ }
menuCommandId_ToggleUI = null;
}
if (typeof GM_registerMenuCommand === 'function') {
const labelUI = config.uiVisible ? 'Hide Width Settings Panel' : 'Show Width Settings Panel';
menuCommandId_ToggleUI = GM_registerMenuCommand(labelUI, async () => {
const newState = !config.uiVisible;
await saveSetting(UI_VISIBLE_KEY, newState);
if (newState) createSettingsUI(); else removeSettingsUI();
updateTampermonkeyMenu();
});
}
}
// --- Shadow DOM Handling ---
function getShadowRoot(element) { try { return element.shadowRoot; } catch (e) { return null; } }
function processElementForShadowDOM(element) {
const shadow = getShadowRoot(element);
if (shadow && shadow.nodeType === Node.DOCUMENT_FRAGMENT_NODE && !allStyleRoots.has(shadow)) {
allStyleRoots.add(shadow);
injectOrUpdateStyle(shadow, WIDTH_STYLE_ID, getCustomWidthConstraintCss());
injectOrUpdateStyle(shadow, LAYOUT_ADJUSTMENTS_STYLE_ID, getLayoutAdjustmentsCss());
return true;
}
return false;
}
function scanExistingShadowDOM() {
try {
document.querySelectorAll('*').forEach(el => {
processElementForShadowDOM(el);
if (el.shadowRoot) el.shadowRoot.querySelectorAll('*').forEach(childEl => processElementForShadowDOM(childEl));
});
} catch (e) { console.error(`[${SCRIPT_NAME}] Error during initial Shadow DOM scan:`, e); }
}
function startDynamicShadowDOMObserver() {
const observer = new MutationObserver(mutationsList => {
for (const mutation of mutationsList) {
if (mutation.type === 'childList') {
mutation.addedNodes.forEach(node => {
if (node.nodeType === Node.ELEMENT_NODE) {
processElementForShadowDOM(node);
node.querySelectorAll('*').forEach(el => processElementForShadowDOM(el));
}
});
}
}
});
if(document.body) observer.observe(document.body, { childList: true, subtree: true });
else document.addEventListener('DOMContentLoaded', () => {
if(document.body) observer.observe(document.body, { childList: true, subtree: true });
});
}
// --- Initialization ---
console.log(`[${SCRIPT_NAME}] v${SCRIPT_VERSION} by ${SCRIPT_AUTHOR} starting...`);
// Race Condition Fix: Hide content initially
const preloadStyle = document.createElement('style');
preloadStyle.id = PRELOAD_STYLE_ID;
preloadStyle.textContent = `.application-main { visibility: hidden !important; }`;
document.head.appendChild(preloadStyle);
if (document.head) allStyleRoots.add(document.head);
else { const rootNode = document.documentElement || document; allStyleRoots.add(rootNode); }
await loadSettings();
applyGlobalHeadStyles();
applyCustomWidthConstraintStyleToAllRoots();
applyLayoutAdjustmentsStyleToAllRoots();
scanExistingShadowDOM();
startDynamicShadowDOMObserver();
if (config.uiVisible) setTimeout(createSettingsUI, 100);
updateTampermonkeyMenu();
// Reveal content
try {
const styleToRemove = document.getElementById(PRELOAD_STYLE_ID);
if (styleToRemove) setTimeout(() => styleToRemove.remove(), 50);
} catch (e) {
document.body.style.visibility = 'visible';
}
// Handle GitHub's Turbo Drive navigation
document.addEventListener("turbo:load", async () => {
allStyleRoots.clear();
if(document.head) allStyleRoots.add(document.head); else allStyleRoots.add(document.documentElement||document);
await loadSettings();
applyCustomWidthConstraintStyleToAllRoots();
applyLayoutAdjustmentsStyleToAllRoots();
scanExistingShadowDOM();
const existingPanel = document.getElementById(SETTINGS_PANEL_ID);
if(config.uiVisible && !existingPanel) setTimeout(createSettingsUI, 100);
else if(!config.uiVisible && existingPanel) removeSettingsUI();
});
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment