darkreader 4.9.101 → 4.9.104

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.
Files changed (3) hide show
  1. package/darkreader.js +167 -58
  2. package/darkreader.mjs +8082 -0
  3. package/package.json +16 -15
package/darkreader.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Dark Reader v4.9.101
2
+ * Dark Reader v4.9.104
3
3
  * https://darkreader.org/
4
4
  */
5
5
 
@@ -371,11 +371,6 @@
371
371
  "onedrive.live.com"
372
372
  ];
373
373
  ({
374
- schemeVersion: 0,
375
- enabled: true,
376
- fetchNews: true,
377
- theme: DEFAULT_THEME,
378
- presets: [],
379
374
  customThemes: filterModeSites.map((url) => {
380
375
  const engine = isChromium
381
376
  ? ThemeEngine.svgFilter
@@ -386,31 +381,9 @@
386
381
  builtIn: true
387
382
  };
388
383
  }),
389
- enabledByDefault: true,
390
- enabledFor: [],
391
- disabledFor: [],
392
- changeBrowserTheme: false,
393
- syncSettings: true,
394
- syncSitesFixes: false,
395
384
  automation: {
396
- enabled: false,
397
- mode: AutomationMode.NONE,
398
- behavior: "OnOff"
399
- },
400
- time: {
401
- activation: "18:00",
402
- deactivation: "9:00"
403
- },
404
- location: {
405
- latitude: null,
406
- longitude: null
407
- },
408
- previewNewDesign: false,
409
- previewNewestDesign: false,
410
- enableForPDF: true,
411
- enableForProtectedPages: false,
412
- enableContextMenus: false,
413
- detectDarkTheme: true
385
+ mode: AutomationMode.NONE
386
+ }
414
387
  });
415
388
 
416
389
  function getMatches(regex, input, group = 0) {
@@ -1000,9 +973,18 @@
1000
973
  const rgbMatch = /^rgba?\([^\(\)]+\)$/;
1001
974
  const hslMatch = /^hsla?\([^\(\)]+\)$/;
1002
975
  const hexMatch = /^#[0-9a-f]+$/i;
976
+ const supportedColorFuncs = [
977
+ "color",
978
+ "color-mix",
979
+ "hwb",
980
+ "lab",
981
+ "lch",
982
+ "oklab",
983
+ "oklch"
984
+ ];
1003
985
  function parse($color) {
1004
986
  const c = $color.trim().toLowerCase();
1005
- if ($color.includes("(from ")) {
987
+ if (c.includes("(from ")) {
1006
988
  return domParseColor(c);
1007
989
  }
1008
990
  if (c.match(rgbMatch)) {
@@ -1023,12 +1005,14 @@
1023
1005
  if (systemColors.has(c)) {
1024
1006
  return getSystemColor(c);
1025
1007
  }
1026
- if ($color === "transparent") {
1008
+ if (c === "transparent") {
1027
1009
  return {r: 0, g: 0, b: 0, a: 0};
1028
1010
  }
1029
1011
  if (
1030
- (c.startsWith("color(") || c.startsWith("color-mix(")) &&
1031
- c.endsWith(")")
1012
+ c.endsWith(")") &&
1013
+ supportedColorFuncs.some(
1014
+ (fn) => c.startsWith(fn) && c[fn.length] === "("
1015
+ )
1032
1016
  ) {
1033
1017
  return domParseColor(c);
1034
1018
  }
@@ -1541,6 +1525,12 @@
1541
1525
 
1542
1526
  function logInfo(...args) {}
1543
1527
  function logWarn(...args) {}
1528
+ function logAssert(...args) {}
1529
+ function ASSERT(description, condition) {
1530
+ if (!condition) {
1531
+ logAssert(description);
1532
+ }
1533
+ }
1544
1534
 
1545
1535
  function removeNode(node) {
1546
1536
  node && node.parentNode && node.parentNode.removeChild(node);
@@ -1549,7 +1539,7 @@
1549
1539
  const MAX_ATTEMPTS_COUNT = 10;
1550
1540
  const RETRY_TIMEOUT = getDuration({seconds: 2});
1551
1541
  const ATTEMPTS_INTERVAL = getDuration({seconds: 10});
1552
- const prevSibling = node.previousSibling;
1542
+ let prevSibling = node.previousSibling;
1553
1543
  let parent = node.parentNode;
1554
1544
  if (!parent) {
1555
1545
  throw new Error(
@@ -1574,6 +1564,11 @@
1574
1564
  start = now;
1575
1565
  } else if (attempts >= MAX_ATTEMPTS_COUNT) {
1576
1566
  if (now - start < ATTEMPTS_INTERVAL) {
1567
+ logWarn(
1568
+ `Node position watcher paused: retry in ${RETRY_TIMEOUT}ms`,
1569
+ node,
1570
+ prevSibling
1571
+ );
1577
1572
  timeoutId = setTimeout(() => {
1578
1573
  start = null;
1579
1574
  attempts = 0;
@@ -1587,22 +1582,40 @@
1587
1582
  }
1588
1583
  if (mode === "head") {
1589
1584
  if (prevSibling && prevSibling.parentNode !== parent) {
1590
- stop();
1591
- return;
1585
+ logWarn(
1586
+ "Sibling moved, moving node to the head end",
1587
+ node,
1588
+ prevSibling,
1589
+ parent
1590
+ );
1591
+ prevSibling = document.head.lastChild;
1592
1592
  }
1593
1593
  }
1594
1594
  if (mode === "prev-sibling") {
1595
1595
  if (prevSibling.parentNode == null) {
1596
+ logWarn(
1597
+ "Unable to restore node position: sibling was removed",
1598
+ node,
1599
+ prevSibling,
1600
+ parent
1601
+ );
1596
1602
  stop();
1597
1603
  return;
1598
1604
  }
1599
1605
  if (prevSibling.parentNode !== parent) {
1606
+ logWarn(
1607
+ "Style was moved to another parent",
1608
+ node,
1609
+ prevSibling,
1610
+ parent
1611
+ );
1600
1612
  updateParent(prevSibling.parentNode);
1601
1613
  }
1602
1614
  }
1603
1615
  if (mode === "head" && !parent.isConnected) {
1604
1616
  parent = document.head;
1605
1617
  }
1618
+ logWarn("Restoring node position", node, prevSibling, parent);
1606
1619
  parent.insertBefore(
1607
1620
  node,
1608
1621
  prevSibling && prevSibling.isConnected
@@ -1857,7 +1870,9 @@
1857
1870
  }
1858
1871
  } else if (isLayerRule(rule)) {
1859
1872
  iterateCSSRules(rule.cssRules, iterate, onImportError);
1860
- } else;
1873
+ } else {
1874
+ logWarn(`CSSRule type not supported`, rule);
1875
+ }
1861
1876
  });
1862
1877
  }
1863
1878
  const shorthandVarDependantProperties = [
@@ -1966,6 +1981,9 @@
1966
1981
  const escapedURL = absoluteURL.replaceAll("'", "\\'");
1967
1982
  return `url('${escapedURL}')`;
1968
1983
  } catch (err) {
1984
+ logWarn(
1985
+ "Not able to replace relative URL with Absolute URL, skipping"
1986
+ );
1969
1987
  return match;
1970
1988
  }
1971
1989
  });
@@ -2387,6 +2405,7 @@
2387
2405
  sh = image.height;
2388
2406
  }
2389
2407
  if (sw === 0 || sh === 0) {
2408
+ logWarn("Image is empty");
2390
2409
  return {
2391
2410
  isDark: false,
2392
2411
  isLight: false,
@@ -3209,6 +3228,7 @@
3209
3228
  }
3210
3229
  const rgb = parseColorWithCache(value);
3211
3230
  if (!rgb) {
3231
+ logWarn("Couldn't parse color", value);
3212
3232
  return null;
3213
3233
  }
3214
3234
  if (prop.includes("background")) {
@@ -3570,6 +3590,7 @@
3570
3590
  return combinedResult;
3571
3591
  };
3572
3592
  } catch (err) {
3593
+ logWarn(`Unable to parse gradient ${value}`, err);
3573
3594
  return null;
3574
3595
  }
3575
3596
  }
@@ -3606,6 +3627,7 @@
3606
3627
  };
3607
3628
  };
3608
3629
  } catch (err) {
3630
+ logWarn(`Unable to parse shadow ${value}`, err);
3609
3631
  return null;
3610
3632
  }
3611
3633
  }
@@ -3626,6 +3648,10 @@
3626
3648
  const thumb = parseColorWithCache(colorsMatch[1]);
3627
3649
  const track = parseColorWithCache(colorsMatch[3]);
3628
3650
  if (!thumb || !track) {
3651
+ logWarn(
3652
+ "Couldn't parse color",
3653
+ ...[thumb, track].filter((c) => !c)
3654
+ );
3629
3655
  return null;
3630
3656
  }
3631
3657
  return (theme) =>
@@ -4414,7 +4440,7 @@
4414
4440
  const {isRaw, color} = parseRawColorValue(input);
4415
4441
  const rgb = parseColorWithCache(color);
4416
4442
  if (rgb) {
4417
- const outputColor = modifyFunction(rgb, theme);
4443
+ const outputColor = modifyFunction(rgb, theme, !isRaw);
4418
4444
  if (isRaw) {
4419
4445
  const outputInRGB = parseColorWithCache(outputColor);
4420
4446
  return outputInRGB
@@ -5165,10 +5191,35 @@
5165
5191
  }
5166
5192
  };
5167
5193
  const shorthandOverrides = {
5168
- background: {
5194
+ "background": {
5169
5195
  customProp: "--darkreader-inline-bg",
5170
5196
  cssProp: "background",
5171
5197
  dataAttr: "data-darkreader-inline-bg"
5198
+ },
5199
+ "border": {
5200
+ customProp: "--darkreader-inline-border-short",
5201
+ cssProp: "border",
5202
+ dataAttr: "data-darkreader-inline-border-short"
5203
+ },
5204
+ "border-bottom": {
5205
+ customProp: "--darkreader-inline-border-bottom-short",
5206
+ cssProp: "border-bottom",
5207
+ dataAttr: "data-darkreader-inline-border-bottom-short"
5208
+ },
5209
+ "border-left": {
5210
+ customProp: "--darkreader-inline-border-left-short",
5211
+ cssProp: "border-left",
5212
+ dataAttr: "data-darkreader-inline-border-left-short"
5213
+ },
5214
+ "border-right": {
5215
+ customProp: "--darkreader-inline-border-right-short",
5216
+ cssProp: "border-right",
5217
+ dataAttr: "data-darkreader-inline-border-right-short"
5218
+ },
5219
+ "border-top": {
5220
+ customProp: "--darkreader-inline-border-top-short",
5221
+ cssProp: "border-top",
5222
+ dataAttr: "data-darkreader-inline-border-top-short"
5172
5223
  }
5173
5224
  };
5174
5225
  const overridesList = Object.values(overrides);
@@ -5604,10 +5655,10 @@
5604
5655
  ) {
5605
5656
  setCustomProp(property, property, value);
5606
5657
  } else if (
5607
- property === "background" &&
5658
+ shorthandOverrides[property] &&
5608
5659
  value.includes("var(")
5609
5660
  ) {
5610
- setCustomProp("background", "background", value);
5661
+ setCustomProp(property, property, value);
5611
5662
  } else {
5612
5663
  const overriddenProp = normalizedPropList[property];
5613
5664
  if (
@@ -5653,6 +5704,7 @@
5653
5704
  srcMetaThemeColor = srcMetaThemeColor || meta.content;
5654
5705
  const color = parseColorWithCache(srcMetaThemeColor);
5655
5706
  if (!color) {
5707
+ logWarn("Invalid meta color", color);
5656
5708
  return;
5657
5709
  }
5658
5710
  meta.content = modifyBackgroundColor(color, theme, false);
@@ -5966,6 +6018,8 @@
5966
6018
  if (hasImports(cssRules, true)) {
5967
6019
  return null;
5968
6020
  }
6021
+ !cssRules &&
6022
+ logWarn("[getRulesSync] cssRules is null, trying again.");
5969
6023
  return cssRules;
5970
6024
  }
5971
6025
  function insertStyle() {
@@ -6010,6 +6064,9 @@
6010
6064
  let cssBasePath;
6011
6065
  if (element instanceof HTMLLinkElement) {
6012
6066
  let [cssRules, accessError] = getRulesOrError();
6067
+ if (accessError) {
6068
+ logWarn(accessError);
6069
+ }
6013
6070
  if (
6014
6071
  (isSafari && !element.sheet) ||
6015
6072
  (!isSafari && !cssRules && !accessError) ||
@@ -6022,12 +6079,16 @@
6022
6079
  );
6023
6080
  await linkLoading(element, loadingLinkId);
6024
6081
  } catch (err) {
6082
+ logWarn(err);
6025
6083
  wasLoadingError = true;
6026
6084
  }
6027
6085
  if (cancelAsyncOperations) {
6028
6086
  return null;
6029
6087
  }
6030
6088
  [cssRules, accessError] = getRulesOrError();
6089
+ if (accessError) {
6090
+ logWarn(accessError);
6091
+ }
6031
6092
  }
6032
6093
  if (cssRules) {
6033
6094
  if (!hasImports(cssRules, false)) {
@@ -6068,7 +6129,9 @@
6068
6129
  } else {
6069
6130
  corsCopy = createCORSCopy(element, fullCSSText);
6070
6131
  }
6071
- } catch (err) {}
6132
+ } catch (err) {
6133
+ logWarn(err);
6134
+ }
6072
6135
  if (corsCopy) {
6073
6136
  corsCopyPositionWatcher = watchForNodePosition(
6074
6137
  corsCopy,
@@ -6081,6 +6144,9 @@
6081
6144
  const rules = getRulesSync();
6082
6145
  if (!rules) {
6083
6146
  if (options.secondRound) {
6147
+ logWarn(
6148
+ "Detected dead-lock at details(), returning early to prevent it."
6149
+ );
6084
6150
  return null;
6085
6151
  }
6086
6152
  if (isLoadingRules || wasLoadingError) {
@@ -6097,6 +6163,7 @@
6097
6163
  }
6098
6164
  })
6099
6165
  .catch((err) => {
6166
+ logWarn(err);
6100
6167
  isLoadingRules = false;
6101
6168
  loadingEnd();
6102
6169
  });
@@ -6178,6 +6245,7 @@
6178
6245
  function safeGetSheetRules() {
6179
6246
  const [cssRules, err] = getRulesOrError();
6180
6247
  if (err) {
6248
+ logWarn(err);
6181
6249
  return null;
6182
6250
  }
6183
6251
  return cssRules;
@@ -6220,8 +6288,10 @@
6220
6288
  }
6221
6289
  moveCount++;
6222
6290
  if (moveCount > maxMoveCount) {
6291
+ logWarn("Style sheet was moved multiple times", element);
6223
6292
  return;
6224
6293
  }
6294
+ logWarn("Restore style", syncStyle, element);
6225
6295
  insertStyle();
6226
6296
  corsCopyPositionWatcher && corsCopyPositionWatcher.skip();
6227
6297
  syncStylePositionWatcher && syncStylePositionWatcher.skip();
@@ -6288,13 +6358,14 @@
6288
6358
  let text;
6289
6359
  if (parsedURL.origin === location.origin) {
6290
6360
  text = await loadAsText(url, "text/css", location.origin);
6361
+ } else {
6362
+ text = await bgFetch({
6363
+ url,
6364
+ responseType: "text",
6365
+ mimeType: "text/css",
6366
+ origin: location.origin
6367
+ });
6291
6368
  }
6292
- text = await bgFetch({
6293
- url,
6294
- responseType: "text",
6295
- mimeType: "text/css",
6296
- origin: location.origin
6297
- });
6298
6369
  writeCSSFetchCache(url, text);
6299
6370
  return text;
6300
6371
  }
@@ -6336,6 +6407,7 @@
6336
6407
  cache
6337
6408
  );
6338
6409
  } catch (err) {
6410
+ logWarn(err);
6339
6411
  importedCSS = "";
6340
6412
  }
6341
6413
  }
@@ -6814,6 +6886,10 @@
6814
6886
  customElementsWhenDefined(tag).then(() => {
6815
6887
  if (elementsDefinitionCallback) {
6816
6888
  const elements = undefinedGroups.get(tag);
6889
+ ASSERT(
6890
+ "recordUndefinedElement() undefined groups should not be empty",
6891
+ elements
6892
+ );
6817
6893
  undefinedGroups.delete(tag);
6818
6894
  elementsDefinitionCallback(Array.from(elements));
6819
6895
  }
@@ -6856,6 +6932,10 @@
6856
6932
  function handleIsDefined(e) {
6857
6933
  canOptimizeUsingProxy = true;
6858
6934
  const tag = e.detail.tag;
6935
+ ASSERT(
6936
+ "handleIsDefined() expects lower-case node names",
6937
+ () => tag.toLowerCase() === tag
6938
+ );
6859
6939
  definedCustomElements.add(tag);
6860
6940
  if (resolvers.has(tag)) {
6861
6941
  const r = resolvers.get(tag);
@@ -6864,6 +6944,10 @@
6864
6944
  }
6865
6945
  }
6866
6946
  async function customElementsWhenDefined(tag) {
6947
+ ASSERT(
6948
+ "customElementsWhenDefined() expects lower-case node names",
6949
+ () => tag.toLowerCase() === tag
6950
+ );
6867
6951
  if (definedCustomElements.has(tag)) {
6868
6952
  return;
6869
6953
  }
@@ -7149,14 +7233,20 @@
7149
7233
  let isIFrame$1 = null;
7150
7234
  let ignoredImageAnalysisSelectors = [];
7151
7235
  let ignoredInlineSelectors = [];
7236
+ const staticStyleMap = new Map();
7152
7237
  function createOrUpdateStyle(className, root = document.head || document) {
7153
7238
  let element = root.querySelector(`.${className}`);
7154
- if (!element) {
7239
+ if (element) {
7240
+ staticStyleMap.set(className, element);
7241
+ } else if (staticStyleMap.has(className)) {
7242
+ element = staticStyleMap.get(className);
7243
+ } else {
7155
7244
  element = document.createElement("style");
7156
7245
  element.classList.add("darkreader");
7157
7246
  element.classList.add(className);
7158
7247
  element.media = "screen";
7159
7248
  element.textContent = "";
7249
+ staticStyleMap.set(className, element);
7160
7250
  }
7161
7251
  return element;
7162
7252
  }
@@ -7170,10 +7260,13 @@
7170
7260
  return element;
7171
7261
  }
7172
7262
  const nodePositionWatchers = new Map();
7173
- function setupNodePositionWatcher(node, alias) {
7263
+ function setupNodePositionWatcher(node, alias, callback) {
7174
7264
  nodePositionWatchers.has(alias) &&
7175
7265
  nodePositionWatchers.get(alias).stop();
7176
- nodePositionWatchers.set(alias, watchForNodePosition(node, "head"));
7266
+ nodePositionWatchers.set(
7267
+ alias,
7268
+ watchForNodePosition(node, "head", callback)
7269
+ );
7177
7270
  }
7178
7271
  function stopStylePositionWatchers() {
7179
7272
  forEach(nodePositionWatchers.values(), (watcher) => watcher.stop());
@@ -7253,7 +7346,9 @@
7253
7346
  `}`
7254
7347
  ].join("\n");
7255
7348
  document.head.insertBefore(variableStyle, inlineStyle.nextSibling);
7256
- setupNodePositionWatcher(variableStyle, "variables");
7349
+ setupNodePositionWatcher(variableStyle, "variables", () =>
7350
+ registerVariablesSheet(variableStyle.sheet)
7351
+ );
7257
7352
  registerVariablesSheet(variableStyle.sheet);
7258
7353
  const rootVarsStyle = createOrUpdateStyle("darkreader--root-vars");
7259
7354
  document.head.insertBefore(rootVarsStyle, variableStyle.nextSibling);
@@ -7341,11 +7436,14 @@
7341
7436
  }
7342
7437
  return modifyForegroundColor(color, theme);
7343
7438
  }
7439
+ logWarn("Couldn't parse CSSTemplate's color.");
7344
7440
  return $color;
7345
7441
  });
7346
7442
  }
7347
7443
  function cleanFallbackStyle() {
7348
- const fallback = document.querySelector(".darkreader--fallback");
7444
+ const fallback =
7445
+ staticStyleMap.get("darkreader--fallback") ||
7446
+ document.querySelector(".darkreader--fallback");
7349
7447
  if (fallback) {
7350
7448
  fallback.textContent = "";
7351
7449
  }
@@ -7458,8 +7556,8 @@
7458
7556
  logInfo(
7459
7557
  `Current amount of styles loading: ${loadingStyles.size}`
7460
7558
  );
7461
- const fallbackStyle = document.querySelector(
7462
- ".darkreader--fallback"
7559
+ const fallbackStyle = createOrUpdateStyle(
7560
+ "darkreader--fallback"
7463
7561
  );
7464
7562
  if (!fallbackStyle.textContent) {
7465
7563
  fallbackStyle.textContent = getModifiedFallbackStyle(
@@ -7519,6 +7617,10 @@
7519
7617
  cleanFallbackStyle();
7520
7618
  return;
7521
7619
  }
7620
+ logWarn(
7621
+ `DOM is ready, but still have styles being loaded.`,
7622
+ loadingStyles
7623
+ );
7522
7624
  }
7523
7625
  function runDynamicStyle() {
7524
7626
  createDynamicStyleOverrides();
@@ -7653,6 +7755,7 @@
7653
7755
  cleanReadyStateCompleteListeners();
7654
7756
  }
7655
7757
  let metaObserver;
7758
+ let headObserver = null;
7656
7759
  function addMetaListener() {
7657
7760
  metaObserver = new MutationObserver(() => {
7658
7761
  if (document.querySelector('meta[name="darkreader-lock"]')) {
@@ -7847,12 +7950,17 @@
7847
7950
  strict: true
7848
7951
  });
7849
7952
  }
7850
- const headObserver = new MutationObserver(() => {
7953
+ headObserver?.disconnect();
7954
+ headObserver = new MutationObserver(() => {
7851
7955
  if (document.head) {
7852
- headObserver.disconnect();
7956
+ headObserver?.disconnect();
7853
7957
  ready();
7854
7958
  }
7855
7959
  });
7960
+ cleaners.push(() => {
7961
+ headObserver?.disconnect();
7962
+ headObserver = null;
7963
+ });
7856
7964
  headObserver.observe(document, {childList: true, subtree: true});
7857
7965
  }
7858
7966
  prevTheme = theme;
@@ -7883,6 +7991,7 @@
7883
7991
  selectors.forEach((selector) =>
7884
7992
  removeNode(document.head.querySelector(selector))
7885
7993
  );
7994
+ staticStyleMap.clear();
7886
7995
  removeProxy();
7887
7996
  }
7888
7997
  shadowRootsWithOverrides.forEach((root) => {