preliminary dark mode - has some problems
This commit is contained in:
parent
b84d2c03ae
commit
0162784897
7 changed files with 219 additions and 0 deletions
5
background.js
Normal file
5
background.js
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
// background.js
|
||||
chrome.browserAction.onClicked.addListener((tab) => {
|
||||
// Send a message to the content script to toggle dark mode
|
||||
chrome.tabs.sendMessage(tab.id, { action: 'toggleDarkMode' });
|
||||
});
|
||||
185
content.js
Normal file
185
content.js
Normal file
|
|
@ -0,0 +1,185 @@
|
|||
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();
|
||||
}
|
||||
BIN
icons/icon128.png
Normal file
BIN
icons/icon128.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
BIN
icons/icon16.png
Normal file
BIN
icons/icon16.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
BIN
icons/icon48.png
Normal file
BIN
icons/icon48.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.2 KiB |
BIN
icons/icon96.png
Normal file
BIN
icons/icon96.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 9.2 KiB |
29
manifest.json
Normal file
29
manifest.json
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
{
|
||||
"manifest_version": 2,
|
||||
"name": "Dark Mode Toggle",
|
||||
"version": "1.0",
|
||||
"description": "Toggle dark mode using inline styles without affecting fingerprinting tools.",
|
||||
"permissions": [
|
||||
"activeTab"
|
||||
],
|
||||
"background": {
|
||||
"scripts": ["background.js"]
|
||||
},
|
||||
"browser_action": {
|
||||
"default_icon": "icons/icon48.png",
|
||||
"default_title": "Toggle Dark Mode"
|
||||
},
|
||||
"content_scripts": [
|
||||
{
|
||||
"matches": ["<all_urls>"],
|
||||
"js": ["content.js"]
|
||||
}
|
||||
],
|
||||
"icons": {
|
||||
"16": "icons/icon16.png",
|
||||
"48": "icons/icon48.png",
|
||||
"96": "icons/icon96.png",
|
||||
"128": "icons/icon128.png"
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Add table
Reference in a new issue