-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Broken Website] www.mozilla.org, SVG background image is not handled correctly #11069
Comments
Further debugging, it seems that this issue is the combination of how different browsers handle SVG image without Debug code, adapted from DR's code. Please navigate to the website and run this code in the console.'use strict'
const MAX_ANALIZE_PIXELS_COUNT = 32 * 32;
const MAX_IMAGE_SIZE = 5 * 1024 * 1024;
let canvas;
let context;
async function readResponseAsDataURL(response) {
const blob = await response.blob();
const dataURL = await (new Promise((resolve) => {
const reader = new FileReader();
reader.onloadend = () => resolve(reader.result);
reader.readAsDataURL(blob);
}));
return dataURL;
}
function createCanvas() {
const maxWidth = MAX_ANALIZE_PIXELS_COUNT;
const maxHeight = MAX_ANALIZE_PIXELS_COUNT;
canvas = document.createElement('canvas');
canvas.width = maxWidth;
canvas.height = maxHeight;
context = canvas.getContext('2d', {willReadFrequently: true});
context.imageSmoothingEnabled = false;
}
async function urlToImage(url) {
return new Promise((resolve, reject) => {
const image = new Image();
image.onload = () => resolve(image);
image.onerror = () => reject(`Unable to load image ${url}`);
image.src = url;
});
}
function getSRGBLightness(r, g, b) {
return (0.2126 * r + 0.7152 * g + 0.0722 * b) / 255;
}
function analyzeImage(image) {
if (!canvas) {
createCanvas();
}
const {naturalWidth, naturalHeight} = image;
if (naturalHeight === 0 || naturalWidth === 0) {
console.log(`logWarn(Image is empty ${image.currentSrc})`);
return {
isDark: false,
isLight: false,
isTransparent: false,
isLarge: false,
isTooLarge: false,
};
}
const size = naturalWidth * naturalHeight * 4;
if (size > MAX_IMAGE_SIZE) {
console.log('Skipped large image analyzing(Larger than 5mb in memory)');
return {
isDark: false,
isLight: false,
isTransparent: false,
isLarge: false,
isTooLarge: true,
};
}
const naturalPixelsCount = naturalWidth * naturalHeight;
const k = Math.min(1, Math.sqrt(MAX_ANALIZE_PIXELS_COUNT / naturalPixelsCount));
const width = Math.ceil(naturalWidth * k);
const height = Math.ceil(naturalHeight * k);
context.clearRect(0, 0, width, height);
context.drawImage(image, 0, 0, naturalWidth, naturalHeight, 0, 0, width, height);
const imageData = context.getImageData(0, 0, width, height);
const d = imageData.data;
const TRANSPARENT_ALPHA_THRESHOLD = 0.05;
const DARK_LIGHTNESS_THRESHOLD = 0.4;
const LIGHT_LIGHTNESS_THRESHOLD = 0.7;
let transparentPixelsCount = 0;
let darkPixelsCount = 0;
let lightPixelsCount = 0;
let i, x, y;
let r, g, b, a;
let l;
for (y = 0; y < height; y++) {
for (x = 0; x < width; x++) {
i = 4 * (y * width + x);
r = d[i + 0];
g = d[i + 1];
b = d[i + 2];
a = d[i + 3];
if (a / 255 < TRANSPARENT_ALPHA_THRESHOLD) {
transparentPixelsCount++;
} else {
l = getSRGBLightness(r, g, b);
if (l < DARK_LIGHTNESS_THRESHOLD) {
darkPixelsCount++;
}
if (l > LIGHT_LIGHTNESS_THRESHOLD) {
lightPixelsCount++;
}
}
}
}
const totalPixelsCount = width * height;
const opaquePixelsCount = totalPixelsCount - transparentPixelsCount;
const DARK_IMAGE_THRESHOLD = 0.7;
const LIGHT_IMAGE_THRESHOLD = 0.7;
const TRANSPARENT_IMAGE_THRESHOLD = 0.1;
const LARGE_IMAGE_PIXELS_COUNT = 800 * 600;
return {
isDark: ((darkPixelsCount / opaquePixelsCount) >= DARK_IMAGE_THRESHOLD),
isLight: ((lightPixelsCount / opaquePixelsCount) >= LIGHT_IMAGE_THRESHOLD),
isTransparent: ((transparentPixelsCount / totalPixelsCount) >= TRANSPARENT_IMAGE_THRESHOLD),
isLarge: (naturalPixelsCount >= LARGE_IMAGE_PIXELS_COUNT),
isTooLarge: false,
};
}
const res = await fetch('https://www.mozilla.org/media/img/logos/social/mastodon-black.eda6d9fda842.svg');
const imageURL = await readResponseAsDataURL(res);
const image = await urlToImage(imageURL);
console.log(analyzeImage(image));
console.log((({ width, height, naturalWidth, naturalHeight }) => ({ width, height, naturalWidth, naturalHeight }))(image)); Debug ResultSecond IconAbout the second icon On FirefoxThe result we get: { isDark: false, isLight: false, isTransparent: false, isLarge: false, isTooLarge: false }
{ width: 0, height: 0, naturalWidth: 0, naturalHeight: 0 } There is an open bug here
We still cannot analyze the image properly due to https://bugzilla.mozilla.org/show_bug.cgi?id=700533 .
On EdgeThe result we get: { isDark: true, isLight: false, isTransparent: true, isLarge: false, isTooLarge: false }
{ width: 150, height: 150, naturalWidth: 150, naturalHeight: 150 } The image vanished because it has My suggestion is replacing darkreader/src/inject/dynamic-theme/image.ts Line 189 in bc3001e
with viewBox="0 0 ${width} ${height}" .
Fourth IconAbout the fourth icon On FirefoxThe result we get is the same as the second icon. On EdgeThe result we get: { isDark: true, isLight: false, isTransparent: false, isLarge: false, isTooLarge: false }
{ width: 150, height: 150, naturalWidth: 150, naturalHeight: 150 } The image is clearly transparent but DR reports it is not, so it fails the check at
Debug code, adapted from DR's code. Please create a simple web page. Local file does not work, I used Node package `http-server`.<!DOCTYPE html>
<html>
<body>
<h1>The canvas element</h1>
<div>
<img id="source" src="https://www.mozilla.org/media/img/logos/social/linkedin-black.5cb4b3466aad.svg" width="100" height="100" />
</div>
<canvas id="myCanvas">Your browser does not support the canvas tag.</canvas>
<script>
const MAX_ANALIZE_PIXELS_COUNT = 32 * 32;
let canvas;
let context;
canvas = document.getElementById('myCanvas');
canvas.width = 200;
canvas.height = 200;
context = canvas.getContext('2d', {willReadFrequently: true});
context.imageSmoothingEnabled = false;
const image = document.getElementById("source");
const {naturalWidth, naturalHeight} = image;
const naturalPixelsCount = naturalWidth * naturalHeight;
const k = Math.min(1, Math.sqrt(MAX_ANALIZE_PIXELS_COUNT / naturalPixelsCount));
const width = Math.ceil(naturalWidth * k);
const height = Math.ceil(naturalHeight * k);
context.clearRect(0, 0, width, height);
context.drawImage(image, 0, 0, naturalWidth, naturalHeight, 0, 0, width, height);
</script>
</body>
</html> The result:
My suggestion is replacing darkreader/src/inject/dynamic-theme/image.ts Line 132 in bc3001e
with context!.drawImage(image, 0, 0, width, height) .
|
Prerequisites
Website Issue Description
The footer icons are not inverted correctly.
On Firefox, some are not inverted.
On Edge, some are vanished, and some are not inverted.
Website Address
https://www.mozilla.org/en-US/firefox/
Steps To Reproduce
Screenshots
Operating System
Windows 10 Pro 19045.2728 64-bit
Web Browser name and version
Mozilla Firefox 111.0.1 (64-bit), Microsoft Edge 112.0.1722.34 (64-bit)
Dark Reader version
4.9.62
Additional Context
To fix the issue, I tried the following in the Dynamic Theme Editor:
The
INVERT
works, butIGNORE IMAGE ANALYSIS
don't.DR still injects its SVG background images into the first and third icons.
The text was updated successfully, but these errors were encountered: