Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // ==UserScript==
- // @name GitHub Enhanced
- // @namespace http://tampermonkey.net/
- // @version 1.7.0
- // @description Customize content width on GitHub pages with a slider. Defaults to GitHub's width. Incorporates layout adjustments. Fixes width input.
- // @author kiranwayne
- // @match https://github.com/*
- // @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.7.0';
- const SCRIPT_AUTHOR = 'kiranwayne';
- const CONFIG_PREFIX = 'githubEnhancedWidth_v1_'; // Prefix for GM_setValue keys
- const MAX_WIDTH_PX_KEY = CONFIG_PREFIX + 'maxWidthPx'; // Stores the user's preferred custom max width
- const USE_DEFAULT_WIDTH_KEY = CONFIG_PREFIX + 'useDefaultWidth'; // Boolean: true if script should not alter width
- const UI_VISIBLE_KEY = CONFIG_PREFIX + 'uiVisible'; // Boolean: true if settings panel is shown
- const WIDTH_STYLE_ID = 'gh-enhanced-width-style'; // ID for the style tag applying custom max-width
- const LAYOUT_ADJUSTMENTS_STYLE_ID = 'gh-enhanced-layout-adjustments-style'; // ID for style tag with layout fixes
- const GLOBAL_STYLE_ID = 'gh-enhanced-global-style'; // ID for global styles (e.g., for the settings panel)
- const SETTINGS_PANEL_ID = 'gh-userscript-settings-panel'; // ID for the settings panel element
- // 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(', ');
- // Default value for the *custom* width slider if the user has never set one.
- // This is NOT the script's initial active width; initially, script uses GitHub's default.
- const SCRIPT_DEFAULT_CUSTOM_WIDTH_PX = 1600;
- const MIN_WIDTH_PX = 1500; // Minimum settable custom width
- const MAX_WIDTH_PX = 3300; // Maximum settable custom width
- const STEP_WIDTH_PX = 20; // Increment/decrement step for slider and number input
- // Holds the current configuration. Loaded from GM storage.
- let config = {
- maxWidthPx: SCRIPT_DEFAULT_CUSTOM_WIDTH_PX, // Fallback, overwritten by loadSettings
- useDefaultWidth: true, // Script defaults to not altering GitHub's width
- uiVisible: false, // Settings panel hidden by default
- };
- // DOM element references for the settings panel
- let settingsPanel = null, widthSlider = null, widthLabel = null, widthInput = null;
- let defaultWidthCheckbox = null;
- let menuCommandId_ToggleUI = null; // ID for the Tampermonkey menu command
- const allStyleRoots = new Set(); // Set of document.head and any discovered Shadow DOM roots
- // --- Helper Functions ---
- /**
- * Loads settings from GM storage into the global `config` object.
- * Defaults are applied if settings are not found.
- */
- 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);
- }
- /**
- * Saves a specific setting to GM storage and updates the global `config` object.
- * @param {string} key - The GM storage key (e.g., MAX_WIDTH_PX_KEY).
- * @param {*} value - The value to save.
- */
- 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; // Ensure internal config is also clamped
- } else { return; } // Do not save if not a valid number
- } else {
- // For boolean settings or other types
- 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 ---
- /**
- * Generates CSS to apply the custom maximum width.
- * Returns an empty string if `config.useDefaultWidth` is true.
- */
- function getCustomWidthConstraintCss() {
- if (config.useDefaultWidth) return '';
- return `${WIDTH_TARGET_SELECTOR} { max-width: ${config.maxWidthPx}px !important; margin-left: auto !important; margin-right: auto !important; }`;
- }
- /**
- * Generates CSS for layout adjustments (e.g., making sidebars use full width).
- * Inspired by the original "Wide GitHub" script.
- * Returns an empty string if `config.useDefaultWidth` is true.
- */
- function getLayoutAdjustmentsCss() {
- if (config.useDefaultWidth) return '';
- return `
- /* Make repository overview sidebar (e.g., "About") use available right space */
- .react-repos-overview-margin { margin-right: 0 !important; }
- /* Ensure specific columns (e.g., on Tags page) can use full width */
- .application-main .col-11 { width: 100% !important; }
- /* Fix alignment of assignees in issue lists at wider views */
- #js-repo-pjax-container .js-issue-row .text-right { max-width: 303px !important; }
- `;
- }
- /**
- * Generates CSS for the settings panel.
- */
- function getGlobalPanelCss() {
- return `
- #${SETTINGS_PANEL_ID} { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 14px; line-height: 1.5; }
- #${SETTINGS_PANEL_ID} input[type=number] { -moz-appearance: textfield !important; } /* Firefox: remove spinners */
- #${SETTINGS_PANEL_ID} input[type=number]::-webkit-inner-spin-button,
- #${SETTINGS_PANEL_ID} input[type=number]::-webkit-outer-spin-button { -webkit-appearance: inner-spin-button !important; opacity: 1 !important; cursor: pointer; } /* Webkit: ensure spinners are visible and styled if browser shows them */
- #${SETTINGS_PANEL_ID} { position: fixed; top: 10px; right: 10px; z-index: 99999; background-color: var(--color-canvas-default, #ffffff); color: var(--color-fg-default, #24292f); border: 1px solid var(--color-border-default, #d0d7de); border-radius: 6px; padding: 16px; box-shadow: var(--color-shadow-large, 0 8px 24px rgba(140,149,159,0.2)); min-width: 300px; }
- #${SETTINGS_PANEL_ID} h4 { margin-top: 0; margin-bottom: 8px; font-size: 16px; font-weight: 600; padding-bottom: 8px; border-bottom: 1px solid var(--color-border-muted, #d8dee4); }
- #${SETTINGS_PANEL_ID} p { margin-top:0; margin-bottom: 4px; font-size: 12px; opacity: 0.8; }
- #${SETTINGS_PANEL_ID} label { font-weight: 400; cursor: pointer; vertical-align: middle; }
- #${SETTINGS_PANEL_ID} input[type="checkbox"] { margin-right: 5px; vertical-align: middle; }
- #${SETTINGS_PANEL_ID} .control-group { margin-bottom: 15px; }
- #${SETTINGS_PANEL_ID} .width-controls-wrapper { display: flex; align-items: center; gap: 10px; margin-top: 8px; }
- #${SETTINGS_PANEL_ID} input[type="range"] { flex-grow: 1; vertical-align: middle; }
- #${SETTINGS_PANEL_ID} input[type="number"] { width: 70px; padding: 5px 8px; background-color: var(--color-input-bg, var(--color-canvas-subtle, #f6f8fa)); color: var(--color-fg-default, #24292f); border: 1px solid var(--color-border-default, #d0d7de); border-radius: 6px; vertical-align: middle; }
- #${SETTINGS_PANEL_ID} .width-value-label { min-width: 55px; font-family: ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace; text-align: right; vertical-align: middle; }
- `;
- }
- // --- Style Injection / Update / Removal Functions ---
- /**
- * Injects or updates a <style> tag with given CSS content into a root node.
- * Handles both document.head and Shadow DOM roots.
- * Removes the style tag if cssContent is empty or null.
- * @param {Node} root - The root node (e.g., document.head or a ShadowRoot).
- * @param {string} styleId - The ID for the <style> tag.
- * @param {string} cssContent - The CSS content.
- */
- function injectOrUpdateStyle(root, styleId, cssContent) {
- if (!root) return;
- let style = root.querySelector(`#${styleId}`);
- if (cssContent && cssContent.trim() !== '') { // Only add/update if there's content
- if (!style) {
- style = document.createElement('style'); style.id = styleId; style.textContent = cssContent;
- // Append to document.head or a ShadowRoot
- 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; // Update existing style
- }
- } else { // If cssContent is empty, remove the style tag
- if (style) style.remove();
- }
- }
- /** Applies global CSS (for settings panel) to document.head. */
- function applyGlobalHeadStyles() {
- if (document.head) injectOrUpdateStyle(document.head, GLOBAL_STYLE_ID, getGlobalPanelCss());
- }
- /** Applies custom width CSS to all known style roots. */
- function applyCustomWidthConstraintStyleToAllRoots() {
- const css = getCustomWidthConstraintCss();
- allStyleRoots.forEach(r => { if(r) injectOrUpdateStyle(r, WIDTH_STYLE_ID, css); });
- }
- /** Applies layout adjustment CSS to all known style roots. */
- function applyLayoutAdjustmentsStyleToAllRoots() {
- const css = getLayoutAdjustmentsCss();
- allStyleRoots.forEach(r => { if(r) injectOrUpdateStyle(r, LAYOUT_ADJUSTMENTS_STYLE_ID, css); });
- }
- // --- UI State Update ---
- /** Updates the settings panel UI elements to reflect the current `config`. */
- function updateUIState() {
- if (settingsPanel && defaultWidthCheckbox && widthSlider && widthLabel && widthInput) {
- defaultWidthCheckbox.checked = config.useDefaultWidth;
- const isCustomWidthEnabled = !config.useDefaultWidth;
- // Disable/enable width controls based on "Use GitHub Default Width"
- [widthSlider, widthInput].forEach(el => el.disabled = !isCustomWidthEnabled);
- const opacityValue = isCustomWidthEnabled ? 1 : 0.5; // Dim controls if disabled
- [widthLabel, widthSlider, widthInput].forEach(el => el.style.opacity = opacityValue);
- // Set slider, input, and label to the stored custom max width
- widthSlider.value = config.maxWidthPx;
- widthInput.value = config.maxWidthPx;
- widthLabel.textContent = `${config.maxWidthPx}px`;
- }
- }
- /** Handles clicks outside the settings panel to close it. */
- async function handleClickOutside(event) {
- if (settingsPanel && document.body.contains(settingsPanel) && !settingsPanel.contains(event.target) && config.uiVisible) {
- await saveSetting(UI_VISIBLE_KEY, false); // Set panel to not visible
- removeSettingsUI();
- updateTampermonkeyMenu(); // Update menu item text
- }
- }
- /** Removes the settings panel UI from the DOM. */
- function removeSettingsUI() {
- if (document) document.removeEventListener('click', handleClickOutside, true);
- settingsPanel = document.getElementById(SETTINGS_PANEL_ID);
- if (settingsPanel) {
- settingsPanel.remove();
- // Clear references to panel elements
- settingsPanel = null; widthSlider = null; widthLabel = null; widthInput = null; defaultWidthCheckbox = null;
- }
- }
- /** Creates and appends the settings panel UI to the DOM. */
- function createSettingsUI() {
- if (document.getElementById(SETTINGS_PANEL_ID) || !config.uiVisible) return; // Don't create if exists or not visible
- if (!document.body) { console.warn(`[${SCRIPT_NAME}] document.body not found, cannot create Settings UI.`); return; }
- settingsPanel = document.createElement('div'); settingsPanel.id = SETTINGS_PANEL_ID;
- // Header section with script name, version, author
- const headerDiv = document.createElement('div');
- const titleElement = document.createElement('h4'); titleElement.textContent = SCRIPT_NAME;
- const versionElement = document.createElement('p'); versionElement.textContent = `Version: ${SCRIPT_VERSION}`;
- const authorElement = document.createElement('p'); authorElement.textContent = `Author: ${SCRIPT_AUTHOR}`;
- headerDiv.append(titleElement, versionElement, authorElement);
- // Width control section
- const widthSection = document.createElement('div'); widthSection.className = 'control-group'; widthSection.style.marginTop = '15px';
- // "Use GitHub Default Width" checkbox
- const defaultWidthDiv = document.createElement('div'); defaultWidthDiv.style.marginBottom = '10px';
- 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.textContent = ' Use GitHub Default Width';
- defaultWidthDiv.append(defaultWidthCheckbox, defaultWidthLabelElement);
- // Custom width controls (slider, number input, label)
- const customWidthControlsDiv = document.createElement('div'); customWidthControlsDiv.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; // HTML5 number input handles step validation
- customWidthControlsDiv.append(widthLabel, widthSlider, widthInput);
- widthSection.append(defaultWidthDiv, customWidthControlsDiv);
- settingsPanel.append(headerDiv, widthSection);
- document.body.appendChild(settingsPanel);
- // Event listener for "Use GitHub Default Width" checkbox
- defaultWidthCheckbox.addEventListener('change', async (e) => {
- await saveSetting(USE_DEFAULT_WIDTH_KEY, e.target.checked);
- // If user unchecks for the first time in a session, ensure config.maxWidthPx is up-to-date
- if (!config.useDefaultWidth && config.maxWidthPx === SCRIPT_DEFAULT_CUSTOM_WIDTH_PX) {
- 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));
- }
- applyCustomWidthConstraintStyleToAllRoots();
- applyLayoutAdjustmentsStyleToAllRoots();
- updateUIState(); // Reflect changes in UI (disabled state, values)
- });
- // Event listener for width slider (live input)
- widthSlider.addEventListener('input', (e) => {
- const nw = parseInt(e.target.value, 10);
- config.maxWidthPx = nw; // Update live config (slider value is inherently clamped by its min/max)
- if (widthLabel) widthLabel.textContent = `${nw}px`;
- if (widthInput) widthInput.value = nw; // Sync number input
- if (!config.useDefaultWidth) applyCustomWidthConstraintStyleToAllRoots(); // Apply style live
- });
- // Event listener for width slider (on change - typically mouse up)
- widthSlider.addEventListener('change', async (e) => {
- const valueToSave = parseInt(e.target.value, 10);
- if (!config.useDefaultWidth) {
- await saveSetting(MAX_WIDTH_PX_KEY, valueToSave);
- } else { // Even if default width is active, save the preferred custom width
- await GM_setValue(MAX_WIDTH_PX_KEY, valueToSave);
- }
- });
- // Event listener for width number input (live input)
- widthInput.addEventListener('input', (e) => {
- let rawValue = e.target.value;
- if (rawValue === '') { // If input is cleared, show current actual value in label
- if (widthLabel) widthLabel.textContent = `${config.maxWidthPx}px`;
- return;
- }
- let nw = parseInt(rawValue, 10);
- if (isNaN(nw)) return; // Do nothing if not a number
- if (widthLabel) widthLabel.textContent = `${nw}px`; // Show typed value in label
- // Sync slider, clamping value for slider's own internal state
- if (widthSlider) {
- if (nw >= MIN_WIDTH_PX && nw <= MAX_WIDTH_PX) widthSlider.value = nw;
- else if (nw < MIN_WIDTH_PX) widthSlider.value = MIN_WIDTH_PX;
- else widthSlider.value = MAX_WIDTH_PX;
- }
- // Apply potentially un-clamped value for immediate visual feedback if custom width is active
- if (!config.useDefaultWidth) {
- const tempCss = `${WIDTH_TARGET_SELECTOR} { max-width: ${nw}px !important; margin-left: auto !important; margin-right: auto !important; }`;
- allStyleRoots.forEach(r => { if(r) injectOrUpdateStyle(r, WIDTH_STYLE_ID, tempCss); });
- }
- });
- // Event listener for width number input (on change - blur or Enter)
- widthInput.addEventListener('change', async (e) => {
- let rawValue = e.target.value; let fw;
- if (rawValue === '') fw = config.maxWidthPx; // If cleared, revert to current config value
- else fw = parseInt(rawValue, 10);
- if (isNaN(fw)) fw = config.maxWidthPx; // If invalid text, revert
- fw = Math.max(MIN_WIDTH_PX, Math.min(MAX_WIDTH_PX, fw)); // Clamp final value
- // Update UI elements to the final clamped value
- e.target.value = fw;
- config.maxWidthPx = fw; // Finalize config.maxWidthPx
- if (widthLabel) widthLabel.textContent = `${fw}px`;
- if (widthSlider) widthSlider.value = fw;
- // Save and apply the final clamped value
- if (!config.useDefaultWidth) {
- await saveSetting(MAX_WIDTH_PX_KEY, fw);
- applyCustomWidthConstraintStyleToAllRoots(); // Apply final clamped style
- } else { // Even if default width is active, save the preferred custom width
- await GM_setValue(MAX_WIDTH_PX_KEY, fw);
- }
- });
- updateUIState(); // Initialize UI element states
- if (document) document.addEventListener('click', handleClickOutside, true); // For closing panel
- applyGlobalHeadStyles(); // Ensure panel styles are present
- }
- /** Updates or registers the Tampermonkey menu command to toggle the settings panel. */
- 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(); // Update label for next time
- });
- }
- }
- // --- Shadow DOM Handling ---
- function getShadowRoot(element) { try { return element.shadowRoot; } catch (e) { return null; } }
- /** Processes an element to find its Shadow DOM root and add it to `allStyleRoots`. */
- function processElementForShadowDOM(element) {
- const shadow = getShadowRoot(element);
- if (shadow && shadow.nodeType === Node.DOCUMENT_FRAGMENT_NODE && !allStyleRoots.has(shadow)) {
- allStyleRoots.add(shadow);
- // Apply current styles to the newly discovered shadow root
- injectOrUpdateStyle(shadow, WIDTH_STYLE_ID, getCustomWidthConstraintCss());
- injectOrUpdateStyle(shadow, LAYOUT_ADJUSTMENTS_STYLE_ID, getLayoutAdjustmentsCss());
- return true;
- }
- return false;
- }
- /** Scans the current document for any existing elements with Shadow DOM. */
- function scanExistingShadowDOM() {
- try {
- document.querySelectorAll('*').forEach(el => {
- processElementForShadowDOM(el);
- // Also check children within a shadow root, if any (for nested custom elements)
- if (el.shadowRoot) el.shadowRoot.querySelectorAll('*').forEach(childEl => processElementForShadowDOM(childEl));
- });
- } catch (e) { console.error(`[${SCRIPT_NAME}] Error during initial Shadow DOM scan:`, e); }
- }
- /** Starts a MutationObserver to detect dynamically added elements with Shadow DOM. */
- 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); // Check the new node
- node.querySelectorAll('*').forEach(el => processElementForShadowDOM(el)); // And its descendants
- }
- });
- }
- }
- });
- if(document.body) observer.observe(document.body, { childList: true, subtree: true });
- else document.addEventListener('DOMContentLoaded', () => { // Fallback if body not ready
- if(document.body) observer.observe(document.body, { childList: true, subtree: true });
- });
- }
- // --- Initialization ---
- console.log(`[${SCRIPT_NAME}] v${SCRIPT_VERSION} by ${SCRIPT_AUTHOR} starting...`);
- // Add document.head to style roots (or documentElement as fallback)
- if (document.head) allStyleRoots.add(document.head);
- else { const rootNode = document.documentElement || document; allStyleRoots.add(rootNode); console.warn(`[${SCRIPT_NAME}] document.head not found at init, using documentElement.`); }
- await loadSettings(); // Load settings from GM storage
- // Apply styles based on loaded configuration
- applyGlobalHeadStyles(); // For the settings panel
- applyCustomWidthConstraintStyleToAllRoots(); // Custom width or nothing if default
- applyLayoutAdjustmentsStyleToAllRoots(); // Layout fixes or nothing if default
- scanExistingShadowDOM(); // Find any shadow roots already on the page
- startDynamicShadowDOMObserver(); // Watch for new shadow roots
- // Create settings panel if it was configured to be visible
- if (config.uiVisible) setTimeout(createSettingsUI, 100); // Delay slightly for page load
- updateTampermonkeyMenu(); // Register menu command
- // Handle GitHub's Turbo Drive navigation
- document.addEventListener("turbo:load", async () => {
- console.log(`[${SCRIPT_NAME}] Turbo:load event detected. Re-initializing styles and panel.`);
- // Clear and re-populate style roots for the new page content
- allStyleRoots.clear();
- if(document.head) allStyleRoots.add(document.head); else allStyleRoots.add(document.documentElement||document);
- await loadSettings(); // Re-load settings in case they were changed in another tab
- // Re-apply styles based on potentially updated settings
- applyCustomWidthConstraintStyleToAllRoots();
- applyLayoutAdjustmentsStyleToAllRoots();
- scanExistingShadowDOM(); // Scan new page content for shadow DOM
- // Re-create or remove settings panel based on current visibility config
- const existingPanel = document.getElementById(SETTINGS_PANEL_ID);
- if(config.uiVisible && !existingPanel) setTimeout(createSettingsUI, 100);
- else if(!config.uiVisible && existingPanel) removeSettingsUI();
- });
- console.log(`[${SCRIPT_NAME}] Initialization complete. Initial useDefaultWidth: ${config.useDefaultWidth}, CustomMaxWidth: ${config.maxWidthPx}`);
- })();
Advertisement
Add Comment
Please, Sign In to add comment