185 lines
7.6 KiB
JavaScript
185 lines
7.6 KiB
JavaScript
let isDarkMode = false; // Track current mode (light or dark)
|
|
|
|
// Color Palette for Dark Mode
|
|
const darkModeStyles = {
|
|
backgroundColor: '#121212', // Dark background for general elements
|
|
color: '#e0e0e0', // General text color
|
|
linkColor: '#bb86fc', // Link color for dark mode
|
|
activeLinkColor: '#ff79c6', // Active link color
|
|
buttonBackground: '#333333', // Button background color for dark mode
|
|
buttonTextColor: '#e0e0e0', // Button text color
|
|
inputBackground: '#333333', // Input background color for dark mode
|
|
inputTextColor: '#e0e0e0', // Input text color
|
|
codeBackground: '#1e1e1e', // Code block background color for dark mode
|
|
borderColor: '#444444', // Border color for inputs, buttons, etc.
|
|
containerBackground: '#181818', // Even darker shade for containers like .s-topbar
|
|
siteSpecificHeaderFooterBackground: '#eeeeee', // Light background color for certain headers
|
|
};
|
|
|
|
// Function to apply dark mode via JavaScript only (without using CSS)
|
|
function applyDarkMode() {
|
|
// Apply the general background and text color to the body
|
|
document.body.style.backgroundColor = darkModeStyles.backgroundColor;
|
|
document.body.style.color = darkModeStyles.color;
|
|
|
|
// 1. Loop through all elements to find light background colors and change them
|
|
const allElements = document.querySelectorAll('*');
|
|
allElements.forEach(el => {
|
|
const computedBackgroundColor = window.getComputedStyle(el).backgroundColor;
|
|
const computedBackgroundImage = window.getComputedStyle(el).backgroundImage;
|
|
|
|
// Check for light backgrounds (RGB or hex-based light colors) and ignore background images
|
|
if (isLightBackground(computedBackgroundColor) && computedBackgroundImage === 'none') {
|
|
el.style.backgroundColor = darkModeStyles.backgroundColor; // Set to dark mode color
|
|
} else if (computedBackgroundImage && (computedBackgroundImage.includes('linear-gradient') || computedBackgroundImage.includes('radial-gradient'))) {
|
|
// Handle gradients with pure white or light colors
|
|
el.style.backgroundImage = adjustLightGradients(computedBackgroundImage);
|
|
}
|
|
|
|
// Apply text color to all elements except code blocks and pre blocks
|
|
if (el.tagName !== 'CODE' && el.tagName !== 'PRE') {
|
|
el.style.color = darkModeStyles.color;
|
|
}
|
|
|
|
// Handle padding and margin issues by checking padding area background
|
|
handlePaddingAndMarginBackground(el);
|
|
});
|
|
|
|
// 2. Handle site-specific elements such as headers and footers (e.g., Craigslist, MDN, etc.)
|
|
const siteSpecificElements = document.querySelectorAll('header, footer, .header, .footer');
|
|
siteSpecificElements.forEach(el => {
|
|
const bgColor = window.getComputedStyle(el).backgroundColor;
|
|
if (bgColor === 'rgb(238, 238, 238)' || bgColor === 'rgba(238, 238, 238, 1)') {
|
|
el.style.backgroundColor = darkModeStyles.siteSpecificHeaderFooterBackground;
|
|
}
|
|
});
|
|
|
|
// 3. Handle other specific elements like buttons, inputs, code blocks, etc.
|
|
handleFormElements();
|
|
handleCodeBlocks();
|
|
handleLinks();
|
|
}
|
|
|
|
// Helper function to determine if a background color is light
|
|
function isLightBackground(rgbColor) {
|
|
if (!rgbColor) return false; // If there's no color or invalid color, return false
|
|
const rgb = rgbColor.match(/^rgba?\((\d+), (\d+), (\d+)/); // Match rgb values
|
|
if (rgb) {
|
|
const r = parseInt(rgb[1], 10);
|
|
const g = parseInt(rgb[2], 10);
|
|
const b = parseInt(rgb[3], 10);
|
|
// Simple luminance calculation to detect light colors
|
|
const luminance = 0.2126 * r + 0.7152 * g + 0.0722 * b;
|
|
return luminance > 150; // Threshold for light background
|
|
}
|
|
return false; // If it's not an RGB value, assume it's not light
|
|
}
|
|
|
|
// Function to adjust light colors in a gradient (specifically pure white or light colors)
|
|
function adjustLightGradients(gradient) {
|
|
const gradientRegex = /(linear-gradient|radial-gradient)\((.*?)\)/;
|
|
return gradient.replace(gradientRegex, (match, type, gradientContent) => {
|
|
// Regex to match rgb or rgba color values in the gradient
|
|
const lightColorRegex = /rgba?\((\d+), (\d+), (\d+)(?:, (\d*\.?\d+))?\)/g;
|
|
|
|
// Replace each light color (e.g., rgb(255, 255, 255)) with a darker color
|
|
const adjustedGradient = gradientContent.replace(lightColorRegex, (colorMatch, r, g, b, a) => {
|
|
// Calculate luminance for detecting light colors
|
|
const luminance = 0.2126 * parseInt(r, 10) + 0.7152 * parseInt(g, 10) + 0.0722 * parseInt(b, 10);
|
|
|
|
// If the luminance is higher than a threshold (200), it's a light color
|
|
if (luminance > 200) {
|
|
// Replace light colors with a dark background color (e.g., #282828 or similar)
|
|
return `rgb(40, 40, 40)`; // Dark theme color
|
|
}
|
|
return colorMatch; // Keep dark colors unchanged
|
|
});
|
|
|
|
// Return the updated gradient
|
|
return `${type}(${adjustedGradient})`;
|
|
});
|
|
}
|
|
|
|
// Function to ensure padding and margin background colors are applied
|
|
function handlePaddingAndMarginBackground(el) {
|
|
const padding = window.getComputedStyle(el).padding;
|
|
const margin = window.getComputedStyle(el).margin;
|
|
const bgColor = window.getComputedStyle(el).backgroundColor;
|
|
|
|
// Check if the element has padding or margin and is missing a background
|
|
if ((padding !== '0px' || margin !== '0px') && (bgColor === 'rgba(0, 0, 0, 0)' || bgColor === 'transparent')) {
|
|
el.style.backgroundColor = darkModeStyles.backgroundColor; // Ensure padding area has a background color
|
|
}
|
|
}
|
|
|
|
// Function to handle links with dark mode styling
|
|
function handleLinks() {
|
|
const links = document.querySelectorAll('a');
|
|
links.forEach(link => {
|
|
link.style.color = darkModeStyles.linkColor;
|
|
if (link.hasAttribute('aria-selected') && link.getAttribute('aria-selected') === 'true') {
|
|
link.style.color = darkModeStyles.activeLinkColor; // Active state color for links
|
|
}
|
|
});
|
|
}
|
|
|
|
// Function to handle form elements (buttons, inputs)
|
|
function handleFormElements() {
|
|
const buttons = document.querySelectorAll('button');
|
|
buttons.forEach(button => {
|
|
button.style.backgroundColor = darkModeStyles.buttonBackground;
|
|
button.style.color = darkModeStyles.buttonTextColor;
|
|
button.style.borderColor = darkModeStyles.borderColor;
|
|
if (button.hasAttribute('aria-pressed') && button.getAttribute('aria-pressed') === 'true') {
|
|
button.style.backgroundColor = darkModeStyles.activeLinkColor; // Active state for buttons
|
|
}
|
|
});
|
|
|
|
const inputs = document.querySelectorAll('input, textarea, select');
|
|
inputs.forEach(input => {
|
|
input.style.backgroundColor = darkModeStyles.inputBackground;
|
|
input.style.color = darkModeStyles.inputTextColor;
|
|
input.style.borderColor = darkModeStyles.borderColor;
|
|
});
|
|
}
|
|
|
|
// Function to handle code blocks with dark mode styling
|
|
function handleCodeBlocks() {
|
|
const codeBlocks = document.querySelectorAll('code, pre');
|
|
codeBlocks.forEach(code => {
|
|
code.style.backgroundColor = darkModeStyles.codeBackground;
|
|
code.style.color = darkModeStyles.color; // Use the dark text color for code
|
|
});
|
|
}
|
|
|
|
// Function to revert to light mode (optional)
|
|
function revertLightMode() {
|
|
// Reset all styles
|
|
document.body.style.backgroundColor = '';
|
|
document.body.style.color = '';
|
|
const allElements = document.querySelectorAll('*');
|
|
allElements.forEach(el => {
|
|
el.style.backgroundColor = '';
|
|
el.style.backgroundImage = '';
|
|
el.style.color = '';
|
|
});
|
|
}
|
|
|
|
// Listen for the toggle dark mode action
|
|
chrome.runtime.onMessage.addListener((message) => {
|
|
if (message.action === 'toggleDarkMode') {
|
|
if (isDarkMode) {
|
|
revertLightMode();
|
|
} else {
|
|
applyDarkMode();
|
|
}
|
|
isDarkMode = !isDarkMode;
|
|
}
|
|
});
|
|
|
|
// Apply dark mode on page load
|
|
if (isDarkMode) {
|
|
applyDarkMode();
|
|
} else {
|
|
revertLightMode();
|
|
}
|