您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Expands blog articles to use full widescreen space by removing restrictive max-width constraints on Substack, Medium, Ghost, WordPress and other platforms
// ==UserScript== // @name Blog Widescreen Responsive // @namespace https://greasyfork.runtimutd.eu.org/users/umsibaba // @version 2.5.0 // @description Expands blog articles to use full widescreen space by removing restrictive max-width constraints on Substack, Medium, Ghost, WordPress and other platforms // @author umsibaba // @match https://*.substack.com/* // @match https://substack.com/* // @match https://*.zerodha.com/* // @match https://*.medium.com/* // @match https://medium.com/* // @match https://*.ghost.io/* // @match https://*.ghost.org/* // @match https://*.wordpress.com/* // @match https://*.wordpress.org/* // @match https://*.blogspot.com/* // @match https://*.blogger.com/* // @match https://*.dev.to/* // @match https://dev.to/* // @match https://*.hashnode.dev/* // @match https://*.notion.site/* // @match https://*.beehiiv.com/* // @match https://*.convertkit.com/* // @match https://*.mailchimp.com/* // @match https://*.github.io/* // @match https://*.netlify.app/* // @match https://*.vercel.app/* // @grant GM_addStyle // @grant GM_getValue // @grant GM_setValue // @grant GM_registerMenuCommand // @supportURL https://greasyfork.runtimutd.eu.org/scripts/yourscriptid/feedback // @license MIT // ==/UserScript== (function() { 'use strict'; // Configuration const CONFIG = { maxWidth: GM_getValue('maxWidth', '95%'), padding: GM_getValue('padding', '2rem'), enabled: GM_getValue('enabled', true), preserveReadability: GM_getValue('preserveReadability', false), animationDuration: '0.3s' }; // Platform-specific selectors using modern CSS techniques const PLATFORM_SELECTORS = { // Substack selectors substack: [ '.single-post', '.post-content', '.reader2-post-content', '.post-header', '.frontend-pencraft-Box-module__Box--4o0Ow', 'article[data-testid="post-content"]', '.post', 'main article' ], // Medium selectors medium: [ 'article', '.postArticle-content', '.meteredContent', 'main article', '[data-testid="storyBody"]', '.ab.cd.ce.cf.cg' ], // Ghost selectors ghost: [ '.post-content', '.post-full-content', 'article.post', '.gh-content', '.gh-article', 'main article' ], // WordPress selectors wordpress: [ '.post-content', '.entry-content', 'article.post', '.single-post-container', 'main article', '.wp-block-post-content' ], // Dev.to selectors devto: [ '#article-wrapper', '.crayons-article', 'article[data-article-path]', 'main .crayons-article__main' ], // Hashnode selectors hashnode: [ '.prose', 'article', '.post-content-wrapper' ], // Generic blog selectors generic: [ 'article', '.post', '.post-content', '.entry-content', '.content', 'main article', '[role="main"] article' ] }; // Detect platform function detectPlatform() { const hostname = window.location.hostname.toLowerCase(); if (hostname.includes('substack')) return 'substack'; if (hostname.includes('medium')) return 'medium'; if (hostname.includes('ghost')) return 'ghost'; if (hostname.includes('wordpress') || hostname.includes('wp.')) return 'wordpress'; if (hostname.includes('dev.to')) return 'devto'; if (hostname.includes('hashnode')) return 'hashnode'; return 'generic'; } // Modern CSS styles using 2024/2025 features function createStyles() { return ` /* Blog Widescreen Responsive - Fixed to expand content, not constrain it */ /* CSS Custom Properties for dynamic theming */ :root { --bwr-max-width: ${CONFIG.maxWidth}; --bwr-padding: ${CONFIG.padding}; --bwr-transition: all ${CONFIG.animationDuration} ease-in-out; --bwr-reading-measure: ${CONFIG.preserveReadability ? '75ch' : 'none'}; } /* Remove restrictive max-width constraints from blog platforms */ ${PLATFORM_SELECTORS[detectPlatform()].concat(PLATFORM_SELECTORS.generic) .map(selector => selector) .join(',\n ')} { max-width: var(--bwr-max-width) !important; width: 100% !important; margin-left: auto !important; margin-right: auto !important; padding-left: var(--bwr-padding) !important; padding-right: var(--bwr-padding) !important; transition: var(--bwr-transition) !important; box-sizing: border-box !important; } /* Override platform-specific narrow constraints */ .bwr-enhanced, .bwr-enhanced * { max-width: none !important; } /* Re-apply our desired max-width only to the main container */ .bwr-enhanced { max-width: var(--bwr-max-width) !important; width: 100% !important; margin: 0 auto !important; padding-left: var(--bwr-padding) !important; padding-right: var(--bwr-padding) !important; } /* Typography enhancement - only if preserveReadability is enabled */ ${CONFIG.preserveReadability ? ` .bwr-enhanced :where(p, li, blockquote) { max-width: var(--bwr-reading-measure) !important; margin-left: auto !important; margin-right: auto !important; }` : ''} /* Responsive images and media - make them use full available width */ .bwr-enhanced :where(img, video, iframe, embed, object, figure) { max-width: 100% !important; width: auto !important; height: auto !important; display: block !important; margin-left: auto !important; margin-right: auto !important; } /* Code blocks responsive handling */ .bwr-enhanced :where(pre, code) { max-width: 100% !important; overflow-x: auto !important; white-space: pre-wrap !important; word-wrap: break-word !important; } /* Platform-specific fixes to remove narrow constraints */ /* Substack specific overrides */ .substack-post-content, .single-post, .post-content, .reader2-post-content, .frontend-pencraft-Box-module__Box--4o0Ow { max-width: var(--bwr-max-width) !important; width: 100% !important; } /* Medium specific overrides */ .postArticle-content, .meteredContent, [data-testid="storyBody"] { max-width: var(--bwr-max-width) !important; width: 100% !important; } /* Ghost specific overrides */ .post-content, .post-full-content, .gh-content, .gh-article { max-width: var(--bwr-max-width) !important; width: 100% !important; } /* WordPress specific overrides */ .entry-content, .post-content, .wp-block-post-content { max-width: var(--bwr-max-width) !important; width: 100% !important; } /* Responsive breakpoints */ @media (max-width: 768px) { .bwr-enhanced { padding-left: 1rem !important; padding-right: 1rem !important; } } @media (min-width: 1600px) { .bwr-enhanced { max-width: 95% !important; } } @media (min-width: 1920px) { .bwr-enhanced { max-width: 90% !important; } } /* Dark mode support */ @media (prefers-color-scheme: dark) { .bwr-enhanced { color-scheme: dark; } } /* Reduced motion support */ @media (prefers-reduced-motion: reduce) { .bwr-enhanced { transition: none !important; } } /* Status indicator */ .bwr-status { position: fixed; top: 10px; right: 10px; background: #4CAF50; color: white; padding: 8px 12px; border-radius: 6px; font-size: 12px; font-family: system-ui, -apple-system, sans-serif; z-index: 10000; opacity: 0; transform: translateX(100%); transition: all 0.3s ease; cursor: pointer; user-select: none; } .bwr-status.show { opacity: 1; transform: translateX(0); } .bwr-status.disabled { background: #f44336; } `; } // Enhanced element detection using modern selectors function findContentElements() { const platform = detectPlatform(); const selectors = PLATFORM_SELECTORS[platform].concat(PLATFORM_SELECTORS.generic); for (const selector of selectors) { const elements = document.querySelectorAll(selector); if (elements.length > 0) { return Array.from(elements).filter(el => { // Use getBoundingClientRect for better detection const rect = el.getBoundingClientRect(); return rect.width > 100 && rect.height > 100; }); } } return []; } // Apply enhancements to elements function applyEnhancements() { if (!CONFIG.enabled) return; const elements = findContentElements(); elements.forEach(element => { if (!element.classList.contains('bwr-enhanced')) { element.classList.add('bwr-enhanced'); // Add container query support for modern browsers if (CSS.supports('container-type: inline-size')) { element.style.containerType = 'inline-size'; } } }); showStatus(`Enhanced ${elements.length} elements`); } // Status notification function showStatus(message) { let status = document.querySelector('.bwr-status'); if (!status) { status = document.createElement('div'); status.className = 'bwr-status'; status.addEventListener('click', toggleScript); document.body.appendChild(status); } status.textContent = CONFIG.enabled ? `✓ BWR: ${message}` : '✗ BWR: Disabled'; status.classList.toggle('disabled', !CONFIG.enabled); status.classList.add('show'); setTimeout(() => { status.classList.remove('show'); }, 3000); } // Toggle script functionality function toggleScript() { CONFIG.enabled = !CONFIG.enabled; GM_setValue('enabled', CONFIG.enabled); if (CONFIG.enabled) { applyEnhancements(); } else { document.querySelectorAll('.bwr-enhanced').forEach(el => { el.classList.remove('bwr-enhanced'); }); } showStatus(CONFIG.enabled ? 'Enabled' : 'Disabled'); } // Settings management function openSettings() { const newMaxWidth = prompt('Enter max width (e.g., 95%, 1400px, or 100%):', CONFIG.maxWidth); if (newMaxWidth) { CONFIG.maxWidth = newMaxWidth; GM_setValue('maxWidth', newMaxWidth); } const newPadding = prompt('Enter side padding (e.g., 2rem, 20px):', CONFIG.padding); if (newPadding) { CONFIG.padding = newPadding; GM_setValue('padding', newPadding); } const preserveReadability = confirm('Limit paragraph width for better readability? (Unchecked = full width)'); CONFIG.preserveReadability = preserveReadability; GM_setValue('preserveReadability', preserveReadability); // Reapply styles with new settings initializeScript(); showStatus('Settings updated'); } // Main initialization function initializeScript() { // Inject CSS GM_addStyle(createStyles()); // Apply enhancements immediately applyEnhancements(); // Use modern ResizeObserver for better performance if (window.ResizeObserver) { const resizeObserver = new ResizeObserver(() => { applyEnhancements(); }); resizeObserver.observe(document.body); } // Fallback to MutationObserver for content changes const mutationObserver = new MutationObserver((mutations) => { let shouldReapply = false; mutations.forEach(mutation => { if (mutation.addedNodes.length > 0) { shouldReapply = true; } }); if (shouldReapply) { setTimeout(applyEnhancements, 100); } }); mutationObserver.observe(document.body, { childList: true, subtree: true }); } // Register menu commands GM_registerMenuCommand('Toggle Blog Widescreen', toggleScript); GM_registerMenuCommand('BWR Settings', openSettings); // Wait for DOM and initialize if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', initializeScript); } else { initializeScript(); } // Handle SPA navigation let lastUrl = location.href; new MutationObserver(() => { const url = location.href; if (url !== lastUrl) { lastUrl = url; setTimeout(applyEnhancements, 500); } }).observe(document, { subtree: true, childList: true }); })();