darkreader 4.9.40 → 4.9.43

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
@@ -90,6 +90,9 @@ const CSS = await collectCSS();
90
90
  const isEnabled = isDarkReaderEnabled();
91
91
  ```
92
92
 
93
+ Be aware, that darkreader will add the `chrome` object onto the `window` object, these are to stub certain functions that
94
+ the code will use. They originate from the webextension-api.
95
+
93
96
  ## Site fixes
94
97
 
95
98
  Automatically syncing the site fixes to every Dark Reader user was disabled because the GitHub team doesn't allow using GitHub as a CDN. Storing these files and making requests to other resources would be expensive and look suspicious. As such, changes are included with each new Dark Reader release.
package/darkreader.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Dark Reader v4.9.40
2
+ * Dark Reader v4.9.43
3
3
  * https://darkreader.org/
4
4
  */
5
5
 
@@ -819,19 +819,16 @@
819
819
  return true;
820
820
  }
821
821
  var url = parseURL(href);
822
- var base = parseURL(location.href);
823
- if (url.protocol !== base.protocol) {
822
+ if (url.protocol !== location.protocol) {
824
823
  return false;
825
824
  }
826
- if (url.hostname !== base.hostname) {
825
+ if (url.hostname !== location.hostname) {
827
826
  return false;
828
827
  }
829
- if (url.port !== base.port) {
828
+ if (url.port !== location.port) {
830
829
  return false;
831
830
  }
832
- var path = /.*\//.exec(url.pathname)[0];
833
- var basePath = /.*\//.exec(base.pathname)[0];
834
- return path === basePath;
831
+ return url.pathname === location.pathname;
835
832
  }
836
833
 
837
834
  function iterateCSSRules(rules, iterate, onMediaRuleError) {
@@ -850,9 +847,9 @@
850
847
  }
851
848
  else if (rule.media) {
852
849
  var media = Array.from(rule.media);
853
- var isScreenOrAll = media.some(function (m) { return m.startsWith('screen') || m.startsWith('all'); });
850
+ var isScreenOrAllOrQuery = media.some(function (m) { return m.startsWith('screen') || m.startsWith('all') || m.startsWith('('); });
854
851
  var isPrintOrSpeech = media.some(function (m) { return m.startsWith('print') || m.startsWith('speech'); });
855
- if (isScreenOrAll || !isPrintOrSpeech) {
852
+ if (isScreenOrAllOrQuery || !isPrintOrSpeech) {
856
853
  iterateCSSRules(rule.cssRules, iterate, onMediaRuleError);
857
854
  }
858
855
  }
@@ -912,7 +909,7 @@
912
909
  }
913
910
  }
914
911
  var cssURLRegex = /url\((('.+?')|(".+?")|([^\)]*?))\)/g;
915
- var cssImportRegex = /@import\s*(url\()?(('.+?')|(".+?")|([^\)]*?))\)?;?/g;
912
+ var cssImportRegex = /@import\s*(url\()?(('.+?')|(".+?")|([^\)]*?))\)? ?(screen)?;?/g;
916
913
  function getCSSURLValue(cssURL) {
917
914
  return cssURL.replace(/^url\((.*)\)$/, '$1').trim().replace(/^"(.*)"$/, '$1').replace(/^'(.*)'$/, '$1');
918
915
  }
@@ -923,7 +920,13 @@
923
920
  function replaceCSSRelativeURLsWithAbsolute($css, cssBasePath) {
924
921
  return $css.replace(cssURLRegex, function (match) {
925
922
  var pathValue = getCSSURLValue(match);
926
- return "url(\"" + getAbsoluteURL(cssBasePath, pathValue) + "\")";
923
+ try {
924
+ return "url(\"" + getAbsoluteURL(cssBasePath, pathValue) + "\")";
925
+ }
926
+ catch (err) {
927
+ logWarn('Not able to replace relative URL with Absolute URL, skipping');
928
+ return match;
929
+ }
927
930
  });
928
931
  }
929
932
  var cssCommentsRegex = /\/\*[\s\S]*?\*\//g;
@@ -2254,7 +2257,8 @@
2254
2257
  function getModifiedFallbackStyle(filter, _a) {
2255
2258
  var strict = _a.strict;
2256
2259
  var lines = [];
2257
- lines.push("html, body, " + (strict ? 'body :not(iframe):not(div[style^="position:absolute;top:0;left:-"]' : 'body > :not(iframe)') + " {");
2260
+ var isMicrosoft = location.hostname.endsWith('microsoft.com');
2261
+ lines.push("html, body, " + (strict ? "body :not(iframe)" + (isMicrosoft ? ':not(div[style^="position:absolute;top:0;left:-"]' : '') : 'body > :not(iframe)') + " {");
2258
2262
  lines.push(" background-color: " + modifyBackgroundColor({ r: 255, g: 255, b: 255 }, filter) + " !important;");
2259
2263
  lines.push(" border-color: " + modifyBorderColor({ r: 64, g: 64, b: 64 }, filter) + " !important;");
2260
2264
  lines.push(" color: " + modifyForegroundColor({ r: 0, g: 0, b: 0 }, filter) + " !important;");
@@ -2787,25 +2791,8 @@
2787
2791
  };
2788
2792
  }
2789
2793
  if (property.startsWith('border') || property.startsWith('outline')) {
2790
- if (sourceValue.endsWith(')')) {
2791
- var colorTypeMatch = sourceValue.match(/((rgb|hsl)a?)\(/);
2792
- if (colorTypeMatch) {
2793
- var index_1 = colorTypeMatch.index;
2794
- return function (theme) {
2795
- var value = insertVarValues(sourceValue, _this.unstableVarValues);
2796
- if (!value) {
2797
- return sourceValue;
2798
- }
2799
- var beginning = sourceValue.substring(0, index_1);
2800
- var color = sourceValue.substring(index_1, sourceValue.length);
2801
- var inserted = insertVarValues(color, _this.unstableVarValues);
2802
- var modified = tryModifyBorderColor(inserted, theme);
2803
- return "" + beginning + modified;
2804
- };
2805
- }
2806
- }
2807
2794
  return function (theme) {
2808
- return replaceCSSVariablesNames(sourceValue, function (v) { return wrapBorderColorVariableName(v); }, function (fallback) { return tryModifyTextColor(fallback, theme); });
2795
+ return replaceCSSVariablesNames(sourceValue, function (v) { return wrapBorderColorVariableName(v); }, function (fallback) { return tryModifyBorderColor(fallback, theme); });
2809
2796
  };
2810
2797
  }
2811
2798
  return null;
@@ -3119,17 +3106,41 @@
3119
3106
  function isConstructedColorVar(value) {
3120
3107
  return value.match(/^\s*(rgb|hsl)a?\(/);
3121
3108
  }
3109
+ var rawValueRegex = /^\d{1,3}, ?\d{1,3}, ?\d{1,3}$/;
3110
+ function parseRawValue(color) {
3111
+ if (rawValueRegex.test(color)) {
3112
+ var splitted = color.split(',');
3113
+ var resultInRGB_1 = 'rgb(';
3114
+ splitted.forEach(function (number) {
3115
+ resultInRGB_1 += number.trim() + ", ";
3116
+ });
3117
+ resultInRGB_1 = resultInRGB_1.substr(0, resultInRGB_1.length - 2);
3118
+ resultInRGB_1 += ')';
3119
+ return { isRaw: true, color: resultInRGB_1 };
3120
+ }
3121
+ return { isRaw: false, color: color };
3122
+ }
3123
+ function handleRawValue(color, theme, modifyFunction) {
3124
+ var _a = parseRawValue(color), isRaw = _a.isRaw, newColor = _a.color;
3125
+ var rgb = tryParseColor(newColor);
3126
+ if (rgb) {
3127
+ var outputColor = modifyFunction(rgb, theme);
3128
+ if (isRaw) {
3129
+ var outputInRGB = tryParseColor(outputColor);
3130
+ return outputInRGB ? outputInRGB.r + ", " + outputInRGB.g + ", " + outputInRGB.b : outputColor;
3131
+ }
3132
+ return outputColor;
3133
+ }
3134
+ return newColor;
3135
+ }
3122
3136
  function tryModifyBgColor(color, theme) {
3123
- var rgb = tryParseColor(color);
3124
- return rgb ? modifyBackgroundColor(rgb, theme) : color;
3137
+ return handleRawValue(color, theme, modifyBackgroundColor);
3125
3138
  }
3126
3139
  function tryModifyTextColor(color, theme) {
3127
- var rgb = tryParseColor(color);
3128
- return rgb ? modifyForegroundColor(rgb, theme) : color;
3140
+ return handleRawValue(color, theme, modifyForegroundColor);
3129
3141
  }
3130
3142
  function tryModifyBorderColor(color, theme) {
3131
- var rgb = tryParseColor(color);
3132
- return rgb ? modifyBorderColor(rgb, theme) : color;
3143
+ return handleRawValue(color, theme, modifyBorderColor);
3133
3144
  }
3134
3145
  function insertVarValues(source, varValues, stack) {
3135
3146
  if (stack === void 0) { stack = new Set(); }
@@ -3615,7 +3626,11 @@
3615
3626
  var property = dec.property, value = dec.value, important = dec.important, sourceValue = dec.sourceValue;
3616
3627
  return property + ": " + (value == null ? sourceValue : value) + (important ? ' !important' : '') + ";";
3617
3628
  };
3618
- var ruleText = selector + " { " + declarations.map(getDeclarationText).join(' ') + " }";
3629
+ var cssRulesText = '';
3630
+ declarations.forEach(function (declarations) {
3631
+ cssRulesText += getDeclarationText(declarations) + " ";
3632
+ });
3633
+ var ruleText = selector + " { " + cssRulesText + " }";
3619
3634
  target.insertRule(ruleText, index);
3620
3635
  }
3621
3636
  var asyncDeclarations = new Map();
@@ -3777,7 +3792,8 @@
3777
3792
  (element instanceof HTMLLinkElement &&
3778
3793
  element.rel &&
3779
3794
  element.rel.toLowerCase().includes('stylesheet') &&
3780
- !element.disabled)) &&
3795
+ !element.disabled &&
3796
+ (isFirefox ? !element.href.startsWith('moz-extension://') : true))) &&
3781
3797
  !element.classList.contains('darkreader') &&
3782
3798
  element.media.toLowerCase() !== 'print' &&
3783
3799
  !element.classList.contains('stylus'));
@@ -3941,10 +3957,7 @@
3941
3957
  _c.label = 5;
3942
3958
  case 5:
3943
3959
  if (cssRules) {
3944
- if (isRelativeHrefOnAbsolutePath(element.href)) {
3945
- return [2, cssRules];
3946
- }
3947
- else if (!hasImports(cssRules, false)) {
3960
+ if (!hasImports(cssRules, false)) {
3948
3961
  return [2, cssRules];
3949
3962
  }
3950
3963
  }
@@ -3990,9 +4003,13 @@
3990
4003
  });
3991
4004
  });
3992
4005
  }
3993
- function details() {
4006
+ function details(options) {
3994
4007
  var rules = getRulesSync();
3995
4008
  if (!rules) {
4009
+ if (options.secondRound) {
4010
+ logWarn('Detected dead-lock at details(), returning early to prevent it.');
4011
+ return null;
4012
+ }
3996
4013
  if (isLoadingRules || wasLoadingError) {
3997
4014
  return null;
3998
4015
  }
@@ -4247,7 +4264,7 @@
4247
4264
  });
4248
4265
  }
4249
4266
  function getCSSImportURL(importDeclaration) {
4250
- return getCSSURLValue(importDeclaration.substring(7).trim().replace(/;$/, ''));
4267
+ return getCSSURLValue(importDeclaration.substring(7).trim().replace(/;$/, '').replace(/screen$/, ''));
4251
4268
  }
4252
4269
  function loadText(url) {
4253
4270
  return __awaiter(this, void 0, void 0, function () {
@@ -4643,13 +4660,14 @@
4643
4660
  };
4644
4661
  }
4645
4662
 
4646
- function injectProxy() {
4663
+ function injectProxy(enableStyleSheetsProxy) {
4647
4664
  document.dispatchEvent(new CustomEvent('__darkreader__inlineScriptsAllowed'));
4648
4665
  var addRuleDescriptor = Object.getOwnPropertyDescriptor(CSSStyleSheet.prototype, 'addRule');
4649
4666
  var insertRuleDescriptor = Object.getOwnPropertyDescriptor(CSSStyleSheet.prototype, 'insertRule');
4650
4667
  var deleteRuleDescriptor = Object.getOwnPropertyDescriptor(CSSStyleSheet.prototype, 'deleteRule');
4651
4668
  var removeRuleDescriptor = Object.getOwnPropertyDescriptor(CSSStyleSheet.prototype, 'removeRule');
4652
- var documentStyleSheetsDescriptor = Object.getOwnPropertyDescriptor(Document.prototype, 'styleSheets');
4669
+ var documentStyleSheetsDescriptor = enableStyleSheetsProxy ?
4670
+ Object.getOwnPropertyDescriptor(Document.prototype, 'styleSheets') : null;
4653
4671
  var shouldWrapHTMLElement = location.hostname.endsWith('baidu.com');
4654
4672
  var getElementsByTagNameDescriptor = shouldWrapHTMLElement ?
4655
4673
  Object.getOwnPropertyDescriptor(Element.prototype, 'getElementsByTagName') : null;
@@ -4660,7 +4678,9 @@
4660
4678
  Object.defineProperty(CSSStyleSheet.prototype, 'removeRule', removeRuleDescriptor);
4661
4679
  document.removeEventListener('__darkreader__cleanUp', cleanUp);
4662
4680
  document.removeEventListener('__darkreader__addUndefinedResolver', addUndefinedResolver);
4663
- Object.defineProperty(Document.prototype, 'styleSheets', documentStyleSheetsDescriptor);
4681
+ if (enableStyleSheetsProxy) {
4682
+ Object.defineProperty(Document.prototype, 'styleSheets', documentStyleSheetsDescriptor);
4683
+ }
4664
4684
  if (shouldWrapHTMLElement) {
4665
4685
  Object.defineProperty(Element.prototype, 'getElementsByTagName', getElementsByTagNameDescriptor);
4666
4686
  }
@@ -4708,14 +4728,14 @@
4708
4728
  }
4709
4729
  function proxyGetElementsByTagName(tagName) {
4710
4730
  var _this = this;
4731
+ if (tagName !== 'style') {
4732
+ return getElementsByTagNameDescriptor.value.call(this, tagName);
4733
+ }
4711
4734
  var getCurrentElementValue = function () {
4712
4735
  var elements = getElementsByTagNameDescriptor.value.call(_this, tagName);
4713
- if (tagName === 'style') {
4714
- elements = Object.setPrototypeOf(__spreadArray([], __read(elements), false).filter(function (element) {
4715
- return !element.classList.contains('darkreader');
4716
- }), NodeList.prototype);
4717
- }
4718
- return elements;
4736
+ return Object.setPrototypeOf(__spreadArray([], __read(elements), false).filter(function (element) {
4737
+ return !element.classList.contains('darkreader');
4738
+ }), NodeList.prototype);
4719
4739
  };
4720
4740
  var elements = getCurrentElementValue();
4721
4741
  var NodeListBehavior = {
@@ -4730,7 +4750,9 @@
4730
4750
  Object.defineProperty(CSSStyleSheet.prototype, 'insertRule', Object.assign({}, insertRuleDescriptor, { value: proxyInsertRule }));
4731
4751
  Object.defineProperty(CSSStyleSheet.prototype, 'deleteRule', Object.assign({}, deleteRuleDescriptor, { value: proxyDeleteRule }));
4732
4752
  Object.defineProperty(CSSStyleSheet.prototype, 'removeRule', Object.assign({}, removeRuleDescriptor, { value: proxyRemoveRule }));
4733
- Object.defineProperty(Document.prototype, 'styleSheets', Object.assign({}, documentStyleSheetsDescriptor, { get: proxyDocumentStyleSheets }));
4753
+ if (enableStyleSheetsProxy) {
4754
+ Object.defineProperty(Document.prototype, 'styleSheets', Object.assign({}, documentStyleSheetsDescriptor, { get: proxyDocumentStyleSheets }));
4755
+ }
4734
4756
  if (shouldWrapHTMLElement) {
4735
4757
  Object.defineProperty(Element.prototype, 'getElementsByTagName', Object.assign({}, getElementsByTagNameDescriptor, { value: proxyGetElementsByTagName }));
4736
4758
  }
@@ -4834,7 +4856,7 @@
4834
4856
  var rootVarsStyle = createOrUpdateStyle('darkreader--root-vars');
4835
4857
  document.head.insertBefore(rootVarsStyle, variableStyle.nextSibling);
4836
4858
  var proxyScript = createOrUpdateScript('darkreader--proxy');
4837
- proxyScript.append("(" + injectProxy + ")()");
4859
+ proxyScript.append("(" + injectProxy + ")(!" + fixes.disableStyleSheetsProxy + ")");
4838
4860
  document.head.insertBefore(proxyScript, rootVarsStyle.nextSibling);
4839
4861
  proxyScript.remove();
4840
4862
  }
@@ -4883,7 +4905,7 @@
4883
4905
  .filter(function (style) { return !styleManagers.has(style); })
4884
4906
  .map(function (style) { return createManager(style); });
4885
4907
  newManagers
4886
- .map(function (manager) { return manager.details(); })
4908
+ .map(function (manager) { return manager.details({ secondRound: false }); })
4887
4909
  .filter(function (detail) { return detail && detail.rules.length > 0; })
4888
4910
  .forEach(function (detail) {
4889
4911
  variablesStore.addRulesForMatching(detail.rules);
@@ -4933,7 +4955,7 @@
4933
4955
  }
4934
4956
  }
4935
4957
  function update() {
4936
- var details = manager.details();
4958
+ var details = manager.details({ secondRound: true });
4937
4959
  if (!details) {
4938
4960
  return;
4939
4961
  }
@@ -5023,7 +5045,7 @@
5023
5045
  var newManagers = stylesToManage
5024
5046
  .map(function (style) { return createManager(style); });
5025
5047
  newManagers
5026
- .map(function (manager) { return manager.details(); })
5048
+ .map(function (manager) { return manager.details({ secondRound: false }); })
5027
5049
  .filter(function (detail) { return detail && detail.rules.length > 0; })
5028
5050
  .forEach(function (detail) {
5029
5051
  variablesStore.addRulesForMatching(detail.rules);
package/index.d.ts CHANGED
@@ -23,6 +23,10 @@ declare namespace DarkReader {
23
23
  * @param isEnabled Boolean `false` value.
24
24
  */
25
25
  function auto(isEnabled: false): void;
26
+ /**
27
+ * Returns if darkreader is enabled.
28
+ */
29
+ function isEnabled(): boolean;
26
30
 
27
31
  /**
28
32
  * Sets a function for making CORS requests.
@@ -146,6 +150,13 @@ declare namespace DarkReader {
146
150
  * Mostly used for wrongly inverted background-images
147
151
  */
148
152
  ignoreImageAnalysis: string[];
153
+
154
+ /**
155
+ * A toggle to disable the proxying of `document.styleSheets`.
156
+ * This is a API-Exclusive option, as it can break legitmate websites,
157
+ * who are using the Dark Reader API.
158
+ */
159
+ disableStyleSheetsProxy: boolean;
149
160
  }
150
161
  }
151
162
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "darkreader",
3
- "version": "4.9.40",
3
+ "version": "4.9.43",
4
4
  "description": "Dark mode for every website",
5
5
  "scripts": {
6
6
  "api": "node tasks/build.js --api",
@@ -96,7 +96,7 @@
96
96
  "puppeteer-core": "10.4.0",
97
97
  "rollup": "2.59.0",
98
98
  "rollup-plugin-istanbul2": "2.0.2",
99
- "rollup-plugin-typescript2": "0.30.0",
99
+ "rollup-plugin-typescript2": "0.31.1",
100
100
  "ts-jest": "27.0.7",
101
101
  "ts-node": "10.4.0",
102
102
  "tsconfig-paths": "3.11.0",