darkreader 4.9.83 → 4.9.84

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -43,7 +43,7 @@ Please note that if you encounter error `Too many open files (os error 24)`, the
43
43
 
44
44
  ### Bundling with official Firefox store signatures (experimental)
45
45
 
46
- Prior to publication, extension stores provide digital signatures for extensions. These digital signatures certify the integrity of the archive (that extension bundle did not get corrupted or bit-rotted) and that extension store preformed very basic extension validation.
46
+ Prior to publication, extension stores provide digital signatures for extensions. These digital signatures certify the integrity of the archive (that extension bundle did not get corrupted or bit-rotted) and that extension store performed very basic extension validation.
47
47
 
48
48
  Dark Reader repository contains these digital signatures and you can add them to the extension bundle. The following will build Dark Reader for Firefox version 4.9.63:
49
49
  ```
@@ -147,7 +147,7 @@ Step 1: change Dark Reader's settings.
147
147
  - Click on the Dark Reader icon.
148
148
  - Click on the `Dev tools` button (in the bottom-right corner).
149
149
  - Click on the `Preview new design button`.
150
- - Enable the `Enable on restricted pages` setting under `Settings` -> `Site list`.
150
+ - Enable the `Enable on restricted pages` setting under `Settings` -> `Advanced`.
151
151
 
152
152
  Step 2: change Firefox's settings.
153
153
 
package/darkreader.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Dark Reader v4.9.83
2
+ * Dark Reader v4.9.84
3
3
  * https://darkreader.org/
4
4
  */
5
5
 
@@ -127,6 +127,7 @@
127
127
  const isMatchMediaChangeEventListenerSupported =
128
128
  typeof MediaQueryList === "function" &&
129
129
  typeof MediaQueryList.prototype.addEventListener === "function";
130
+ const isLayerRuleSupported = typeof CSSLayerBlockRule === "function";
130
131
  (() => {
131
132
  const m = userAgent.match(/chrom(?:e|ium)(?:\/| )([^ ]+)/);
132
133
  if (m && m[1]) {
@@ -1156,7 +1157,7 @@
1156
1157
  if (layerRules.has(rule)) {
1157
1158
  return true;
1158
1159
  }
1159
- if (rule instanceof CSSLayerBlockRule) {
1160
+ if (isLayerRuleSupported && rule instanceof CSSLayerBlockRule) {
1160
1161
  layerRules.add(rule);
1161
1162
  return true;
1162
1163
  }
@@ -2348,18 +2349,10 @@
2348
2349
  isDark: false,
2349
2350
  isLight: false,
2350
2351
  isTransparent: false,
2351
- isLarge: false,
2352
- isTooLarge: false
2353
- };
2354
- }
2355
- if (sw * sh > LARGE_IMAGE_PIXELS_COUNT) {
2356
- return {
2357
- isDark: false,
2358
- isLight: false,
2359
- isTransparent: false,
2360
- isLarge: true
2352
+ isLarge: false
2361
2353
  };
2362
2354
  }
2355
+ const isLarge = sw * sh > LARGE_IMAGE_PIXELS_COUNT;
2363
2356
  const sourcePixelsCount = sw * sh;
2364
2357
  const k = Math.min(
2365
2358
  1,
@@ -2412,7 +2405,7 @@
2412
2405
  isTransparent:
2413
2406
  transparentPixelsCount / totalPixelsCount >=
2414
2407
  TRANSPARENT_IMAGE_THRESHOLD,
2415
- isLarge: false
2408
+ isLarge
2416
2409
  };
2417
2410
  }
2418
2411
  let isBlobURLSupported = null;
@@ -2745,6 +2738,11 @@
2745
2738
  ` border-color: ${modifyBorderColor({r: 128, g: 128, b: 128}, theme)};`
2746
2739
  );
2747
2740
  lines.push("}");
2741
+ lines.push("mark {");
2742
+ lines.push(
2743
+ ` color: ${modifyForegroundColor({r: 0, g: 0, b: 0}, theme)};`
2744
+ );
2745
+ lines.push("}");
2748
2746
  lines.push("::placeholder {");
2749
2747
  lines.push(
2750
2748
  ` color: ${modifyForegroundColor({r: 169, g: 169, b: 169}, theme)};`
@@ -2766,6 +2764,10 @@
2766
2764
  if (theme.selectionColor) {
2767
2765
  lines.push(getModifiedSelectionStyle(theme));
2768
2766
  }
2767
+ if (isLayerRuleSupported) {
2768
+ lines.unshift("@layer {");
2769
+ lines.push("}");
2770
+ }
2769
2771
  return lines.join("\n");
2770
2772
  }
2771
2773
  function getSelectionColor(theme) {
@@ -3100,9 +3102,9 @@
3100
3102
  const logSrc = imageDetails.src.startsWith("data:")
3101
3103
  ? "data:"
3102
3104
  : imageDetails.src;
3103
- if (isLarge) {
3104
- logInfo(`Not modifying too large image ${logSrc}`);
3105
- result = null;
3105
+ if (isLarge && isLight && !isTransparent && theme.mode === 1) {
3106
+ logInfo(`Hiding large light image ${logSrc}`);
3107
+ result = "none";
3106
3108
  } else if (
3107
3109
  isDark &&
3108
3110
  isTransparent &&
@@ -4155,6 +4157,11 @@
4155
4157
  "}"
4156
4158
  ].join("\n");
4157
4159
  })
4160
+ .concat([
4161
+ "[data-darkreader-inline-invert] {",
4162
+ " filter: invert(100%) hue-rotate(180deg);",
4163
+ "}"
4164
+ ])
4158
4165
  .join("\n");
4159
4166
  }
4160
4167
  function getInlineStyleElements(root) {
@@ -4292,7 +4299,23 @@
4292
4299
  attrObservers.clear();
4293
4300
  }
4294
4301
  const inlineStyleCache = new WeakMap();
4302
+ const svgInversionCache = new WeakSet();
4303
+ const svgAnalysisConditionCache = new WeakMap();
4295
4304
  const themeProps = ["brightness", "contrast", "grayscale", "sepia", "mode"];
4305
+ function shouldAnalyzeSVGAsImage(svg) {
4306
+ if (svgAnalysisConditionCache.has(svg)) {
4307
+ return svgAnalysisConditionCache.get(svg);
4308
+ }
4309
+ const shouldAnalyze = Boolean(
4310
+ svg &&
4311
+ (svg.role === "img" ||
4312
+ svg.parentElement?.role === "img" ||
4313
+ svg.getAttribute("class")?.includes("logo") ||
4314
+ svg.parentElement?.getAttribute("class")?.includes("logo"))
4315
+ );
4316
+ svgAnalysisConditionCache.set(svg, shouldAnalyze);
4317
+ return shouldAnalyze;
4318
+ }
4296
4319
  function getInlineStyleCacheKey(el, theme) {
4297
4320
  return INLINE_STYLE_ATTRS.map(
4298
4321
  (attr) => `${attr}="${el.getAttribute(attr)}"`
@@ -4401,6 +4424,46 @@
4401
4424
  return;
4402
4425
  }
4403
4426
  }
4427
+ const isSVGElement = element instanceof SVGElement;
4428
+ const svg = isSVGElement
4429
+ ? element.ownerSVGElement ??
4430
+ (element instanceof SVGSVGElement ? element : null)
4431
+ : null;
4432
+ if (isSVGElement && theme.mode === 1 && svg) {
4433
+ if (svgInversionCache.has(svg)) {
4434
+ return;
4435
+ }
4436
+ if (shouldAnalyzeSVGAsImage(svg)) {
4437
+ svgInversionCache.add(svg);
4438
+ const handleSVGRoot = () => {
4439
+ let svgString = svg.outerHTML;
4440
+ svgString = svgString.replaceAll(
4441
+ '<style class="darkreader darkreader--sync" media="screen"></style>',
4442
+ ""
4443
+ );
4444
+ const dataURL = `data:image/svg+xml;base64,${btoa(svgString)}`;
4445
+ getImageDetails(dataURL).then((details) => {
4446
+ if (
4447
+ (details.isDark && details.isTransparent) ||
4448
+ (details.isLarge &&
4449
+ details.isLight &&
4450
+ !details.isTransparent)
4451
+ ) {
4452
+ svg.setAttribute(
4453
+ "data-darkreader-inline-invert",
4454
+ ""
4455
+ );
4456
+ }
4457
+ });
4458
+ };
4459
+ if (isReadyStateComplete()) {
4460
+ handleSVGRoot();
4461
+ } else {
4462
+ addReadyStateCompleteListener(handleSVGRoot);
4463
+ }
4464
+ return;
4465
+ }
4466
+ }
4404
4467
  if (element.hasAttribute("bgcolor")) {
4405
4468
  let value = element.getAttribute("bgcolor");
4406
4469
  if (
@@ -4433,7 +4496,7 @@
4433
4496
  }
4434
4497
  setCustomProp("color", "color", value);
4435
4498
  }
4436
- if (element instanceof SVGElement) {
4499
+ if (isSVGElement) {
4437
4500
  if (element.hasAttribute("fill")) {
4438
4501
  const SMALL_SVG_LIMIT = 32;
4439
4502
  const value = element.getAttribute("fill");
package/index.d.ts CHANGED
@@ -153,7 +153,7 @@ declare namespace DarkReader {
153
153
 
154
154
  /**
155
155
  * A toggle to disable the proxying of `document.styleSheets`.
156
- * This is a API-Exclusive option, as it can break legitmate websites,
156
+ * This is a API-Exclusive option, as it can break legitimate websites,
157
157
  * who are using the Dark Reader API.
158
158
  */
159
159
  disableStyleSheetsProxy: boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "darkreader",
3
- "version": "4.9.83",
3
+ "version": "4.9.84",
4
4
  "description": "Dark mode for every website",
5
5
  "scripts": {
6
6
  "api": "node --max-old-space-size=3072 tasks/cli.js build --api",