Greasy Fork is available in English.
Makes blog articles responsive on widescreen monitors by utilizing empty sidebar space on Substack, Medium, Ghost, WordPress and other platforms
当前为
// ==UserScript==
// @name Blog Widescreen Responsive
// @namespace http://greasyfork.icu/users/yourusername
// @version 2.4.0
// @description Makes blog articles responsive on widescreen monitors by utilizing empty sidebar space on Substack, Medium, Ghost, WordPress and other platforms
// @author YourName
// @match https://*.substack.com/*
// @match https://*thedailybrief.zerodha.com/*
// @match https://substack.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 http://greasyfork.icu/scripts/yourscriptid/feedback
// @license MIT
// ==/UserScript==
(function() {
'use strict';
// Configuration
const CONFIG = {
maxWidth: GM_getValue('maxWidth', '1400px'),
padding: GM_getValue('padding', '2rem'),
enabled: GM_getValue('enabled', true),
preserveReadability: GM_getValue('preserveReadability', true),
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 - Enhanced with modern CSS */
/* 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'};
}
/* Modern container query support */
@container (min-width: 1200px) {
.bwr-enhanced {
container-type: inline-size;
}
}
/* Enhanced selectors using :is() and :where() for better performance */
${PLATFORM_SELECTORS[detectPlatform()].concat(PLATFORM_SELECTORS.generic)
.map(selector => `${selector}:is(.bwr-enhanced)`)
.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;
}
/* Typography enhancement for readability */
.bwr-enhanced :where(p, li, blockquote, .prose) {
max-width: var(--bwr-reading-measure);
${CONFIG.preserveReadability ? 'margin-left: auto; margin-right: auto;' : ''}
}
/* Responsive images and media */
.bwr-enhanced :where(img, video, iframe, embed, object) {
max-width: 100% !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 enhancements using CSS nesting */
.bwr-enhanced {
/* Substack specific */
&:has(.frontend-pencraft-Box-module__Box--4o0Ow) {
.frontend-pencraft-Box-module__Box--4o0Ow {
max-width: none !important;
}
}
/* Medium specific */
&:has(.meteredContent) {
.meteredContent {
max-width: none !important;
}
}
/* WordPress specific */
&:has(.wp-block-post-content) {
.wp-block-post-content {
max-width: none !important;
}
}
}
/* Responsive breakpoints using modern syntax */
@media (max-width: 768px) {
.bwr-enhanced {
padding-left: 1rem !important;
padding-right: 1rem !important;
}
}
@media (min-width: 1600px) {
.bwr-enhanced {
max-width: 1600px !important;
}
}
@media (min-width: 1920px) {
.bwr-enhanced {
max-width: 1800px !important;
}
}
/* Dark mode support using color-scheme */
@media (prefers-color-scheme: dark) {
.bwr-enhanced {
/* Inherit platform's dark mode colors */
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., 1400px):', CONFIG.maxWidth);
if (newMaxWidth) {
CONFIG.maxWidth = newMaxWidth;
GM_setValue('maxWidth', newMaxWidth);
}
const newPadding = prompt('Enter padding (e.g., 2rem):', CONFIG.padding);
if (newPadding) {
CONFIG.padding = newPadding;
GM_setValue('padding', newPadding);
}
const preserveReadability = confirm('Preserve reading line length for better readability?');
CONFIG.preserveReadability = preserveReadability;
GM_setValue('preserveReadability', preserveReadability);
// Reapply styles with new settings
initializeScript();
}
// 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 });
})();