darkreader 4.9.118 → 4.9.120
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/LICENSE +1 -1
- package/darkreader.js +330 -98
- package/darkreader.mjs +326 -98
- package/index.d.ts +8 -0
- package/package.json +22 -22
package/LICENSE
CHANGED
package/darkreader.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Dark Reader v4.9.
|
|
2
|
+
* Dark Reader v4.9.120
|
|
3
3
|
* https://darkreader.org/
|
|
4
4
|
*/
|
|
5
5
|
|
|
@@ -1041,54 +1041,155 @@
|
|
|
1041
1041
|
}
|
|
1042
1042
|
return null;
|
|
1043
1043
|
}
|
|
1044
|
-
|
|
1044
|
+
const C_0 = "0".charCodeAt(0);
|
|
1045
|
+
const C_9 = "9".charCodeAt(0);
|
|
1046
|
+
const C_e = "e".charCodeAt(0);
|
|
1047
|
+
const C_DOT = ".".charCodeAt(0);
|
|
1048
|
+
const C_PLUS = "+".charCodeAt(0);
|
|
1049
|
+
const C_MINUS = "-".charCodeAt(0);
|
|
1050
|
+
const C_SPACE = " ".charCodeAt(0);
|
|
1051
|
+
const C_COMMA = ",".charCodeAt(0);
|
|
1052
|
+
const C_SLASH = "/".charCodeAt(0);
|
|
1053
|
+
const C_PERCENT = "%".charCodeAt(0);
|
|
1054
|
+
function getNumbersFromString(input, range, units) {
|
|
1045
1055
|
const numbers = [];
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
const
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1056
|
+
const searchStart = input.indexOf("(") + 1;
|
|
1057
|
+
const searchEnd = input.length - 1;
|
|
1058
|
+
let numStart = -1;
|
|
1059
|
+
let unitStart = -1;
|
|
1060
|
+
const push = (matchEnd) => {
|
|
1061
|
+
const numEnd = unitStart > -1 ? unitStart : matchEnd;
|
|
1062
|
+
const $num = input.slice(numStart, numEnd);
|
|
1063
|
+
let n = parseFloat($num);
|
|
1064
|
+
const r = range[numbers.length];
|
|
1065
|
+
if (unitStart > -1) {
|
|
1066
|
+
const unit = input.slice(unitStart, matchEnd);
|
|
1067
|
+
const u = units[unit];
|
|
1068
|
+
if (u != null) {
|
|
1069
|
+
n *= r / u;
|
|
1070
|
+
}
|
|
1071
|
+
}
|
|
1072
|
+
if (r > 1) {
|
|
1073
|
+
n = Math.round(n);
|
|
1074
|
+
}
|
|
1075
|
+
numbers.push(n);
|
|
1076
|
+
numStart = -1;
|
|
1077
|
+
unitStart = -1;
|
|
1078
|
+
};
|
|
1079
|
+
for (let i = searchStart; i < searchEnd; i++) {
|
|
1080
|
+
const c = input.charCodeAt(i);
|
|
1081
|
+
const isNumChar =
|
|
1082
|
+
(c >= C_0 && c <= C_9) ||
|
|
1083
|
+
c === C_DOT ||
|
|
1084
|
+
c === C_PLUS ||
|
|
1085
|
+
c === C_MINUS ||
|
|
1086
|
+
c === C_e;
|
|
1087
|
+
const isDelimiter = c === C_SPACE || c === C_COMMA || c === C_SLASH;
|
|
1088
|
+
if (isNumChar) {
|
|
1089
|
+
if (numStart === -1) {
|
|
1090
|
+
numStart = i;
|
|
1091
|
+
}
|
|
1092
|
+
} else if (numStart > -1) {
|
|
1093
|
+
if (isDelimiter) {
|
|
1094
|
+
push(i);
|
|
1095
|
+
} else if (unitStart === -1) {
|
|
1096
|
+
unitStart = i;
|
|
1097
|
+
}
|
|
1098
|
+
}
|
|
1099
|
+
}
|
|
1100
|
+
if (numStart > -1) {
|
|
1101
|
+
push(searchEnd);
|
|
1064
1102
|
}
|
|
1065
1103
|
return numbers;
|
|
1066
1104
|
}
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
const
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1105
|
+
const rgbRange = [255, 255, 255, 1];
|
|
1106
|
+
const rgbUnits = {"%": 100};
|
|
1107
|
+
function getRGBValues(input) {
|
|
1108
|
+
const CHAR_CODE_0 = 48;
|
|
1109
|
+
const length = input.length;
|
|
1110
|
+
let i = 0;
|
|
1111
|
+
let digitsCount = 0;
|
|
1112
|
+
let digitSequence = false;
|
|
1113
|
+
let floatDigitsCount = -1;
|
|
1114
|
+
let delimiter = C_SPACE;
|
|
1115
|
+
let channel = -1;
|
|
1116
|
+
let result = null;
|
|
1117
|
+
while (i < length) {
|
|
1118
|
+
const c = input.charCodeAt(i);
|
|
1119
|
+
if ((c >= C_0 && c <= C_9) || c === C_DOT) {
|
|
1120
|
+
if (!digitSequence) {
|
|
1121
|
+
digitSequence = true;
|
|
1122
|
+
digitsCount = 0;
|
|
1123
|
+
floatDigitsCount = -1;
|
|
1124
|
+
channel++;
|
|
1125
|
+
if (channel === 3 && result) {
|
|
1126
|
+
result[3] = 0;
|
|
1127
|
+
}
|
|
1128
|
+
if (channel > 3) {
|
|
1129
|
+
return null;
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
1132
|
+
if (c === C_DOT) {
|
|
1133
|
+
if (floatDigitsCount > 0) {
|
|
1134
|
+
return null;
|
|
1135
|
+
}
|
|
1136
|
+
floatDigitsCount = 0;
|
|
1080
1137
|
} else {
|
|
1081
|
-
|
|
1138
|
+
const d = c - CHAR_CODE_0;
|
|
1139
|
+
if (!result) {
|
|
1140
|
+
result = [0, 0, 0, 1];
|
|
1141
|
+
}
|
|
1142
|
+
if (floatDigitsCount > -1) {
|
|
1143
|
+
floatDigitsCount++;
|
|
1144
|
+
result[channel] += d / 10 ** floatDigitsCount;
|
|
1145
|
+
} else {
|
|
1146
|
+
digitsCount++;
|
|
1147
|
+
if (digitsCount > 3) {
|
|
1148
|
+
return null;
|
|
1149
|
+
}
|
|
1150
|
+
result[channel] = result[channel] * 10 + d;
|
|
1151
|
+
}
|
|
1082
1152
|
}
|
|
1083
|
-
|
|
1084
|
-
|
|
1153
|
+
} else if (c === C_PERCENT) {
|
|
1154
|
+
if (
|
|
1155
|
+
channel < 0 ||
|
|
1156
|
+
channel > 3 ||
|
|
1157
|
+
delimiter !== C_SPACE ||
|
|
1158
|
+
!result
|
|
1159
|
+
) {
|
|
1160
|
+
return null;
|
|
1085
1161
|
}
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1162
|
+
result[channel] =
|
|
1163
|
+
channel < 3
|
|
1164
|
+
? Math.round((result[channel] * 255) / 100)
|
|
1165
|
+
: result[channel] / 100;
|
|
1166
|
+
digitSequence = false;
|
|
1167
|
+
} else {
|
|
1168
|
+
digitSequence = false;
|
|
1169
|
+
if (c === C_SPACE) {
|
|
1170
|
+
if (channel === 0) {
|
|
1171
|
+
delimiter = c;
|
|
1172
|
+
}
|
|
1173
|
+
} else if (c === C_COMMA) {
|
|
1174
|
+
if (channel === -1) {
|
|
1175
|
+
return null;
|
|
1176
|
+
}
|
|
1177
|
+
delimiter = C_COMMA;
|
|
1178
|
+
} else if (c === C_SLASH) {
|
|
1179
|
+
if (channel !== 2 || delimiter !== C_SPACE) {
|
|
1180
|
+
return null;
|
|
1181
|
+
}
|
|
1182
|
+
} else {
|
|
1183
|
+
return null;
|
|
1184
|
+
}
|
|
1185
|
+
}
|
|
1186
|
+
i++;
|
|
1187
|
+
}
|
|
1188
|
+
if (channel < 2 || channel > 3) {
|
|
1189
|
+
return null;
|
|
1190
|
+
}
|
|
1191
|
+
return result;
|
|
1089
1192
|
}
|
|
1090
|
-
const rgbRange = [255, 255, 255, 1];
|
|
1091
|
-
const rgbUnits = {"%": 100};
|
|
1092
1193
|
function parseRGB($rgb) {
|
|
1093
1194
|
const [r, g, b, a = 1] = getNumbersFromString($rgb, rgbRange, rgbUnits);
|
|
1094
1195
|
if (r == null || g == null || b == null || a == null) {
|
|
@@ -1105,29 +1206,48 @@
|
|
|
1105
1206
|
}
|
|
1106
1207
|
return hslToRGB({h, s, l, a});
|
|
1107
1208
|
}
|
|
1209
|
+
const C_A = "A".charCodeAt(0);
|
|
1210
|
+
const C_F = "F".charCodeAt(0);
|
|
1211
|
+
const C_a = "a".charCodeAt(0);
|
|
1212
|
+
const C_f = "f".charCodeAt(0);
|
|
1108
1213
|
function parseHex($hex) {
|
|
1109
|
-
const
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1214
|
+
const length = $hex.length;
|
|
1215
|
+
const digitCount = length - 1;
|
|
1216
|
+
const isShort = digitCount === 3 || digitCount === 4;
|
|
1217
|
+
const isLong = digitCount === 6 || digitCount === 8;
|
|
1218
|
+
if (!isShort && !isLong) {
|
|
1219
|
+
return null;
|
|
1220
|
+
}
|
|
1221
|
+
const hex = (i) => {
|
|
1222
|
+
const c = $hex.charCodeAt(i);
|
|
1223
|
+
if (c >= C_A && c <= C_F) {
|
|
1224
|
+
return c + 10 - C_A;
|
|
1225
|
+
}
|
|
1226
|
+
if (c >= C_a && c <= C_f) {
|
|
1227
|
+
return c + 10 - C_a;
|
|
1228
|
+
}
|
|
1229
|
+
return c - C_0;
|
|
1230
|
+
};
|
|
1231
|
+
let r;
|
|
1232
|
+
let g;
|
|
1233
|
+
let b;
|
|
1234
|
+
let a = 1;
|
|
1235
|
+
if (isShort) {
|
|
1236
|
+
r = hex(1) * 17;
|
|
1237
|
+
g = hex(2) * 17;
|
|
1238
|
+
b = hex(3) * 17;
|
|
1239
|
+
if (digitCount === 4) {
|
|
1240
|
+
a = (hex(4) * 17) / 255;
|
|
1241
|
+
}
|
|
1242
|
+
} else {
|
|
1243
|
+
r = hex(1) * 16 + hex(2);
|
|
1244
|
+
g = hex(3) * 16 + hex(4);
|
|
1245
|
+
b = hex(5) * 16 + hex(6);
|
|
1246
|
+
if (digitCount === 8) {
|
|
1247
|
+
a = (hex(7) * 16 + hex(8)) / 255;
|
|
1128
1248
|
}
|
|
1129
1249
|
}
|
|
1130
|
-
return
|
|
1250
|
+
return {r, g, b, a};
|
|
1131
1251
|
}
|
|
1132
1252
|
function getColorByName($color) {
|
|
1133
1253
|
const n = knownColors.get($color);
|
|
@@ -1921,13 +2041,6 @@
|
|
|
1921
2041
|
})
|
|
1922
2042
|
: null;
|
|
1923
2043
|
function iterateCSSDeclarations(style, iterate) {
|
|
1924
|
-
forEach(style, (property) => {
|
|
1925
|
-
const value = style.getPropertyValue(property).trim();
|
|
1926
|
-
if (!value) {
|
|
1927
|
-
return;
|
|
1928
|
-
}
|
|
1929
|
-
iterate(property, value);
|
|
1930
|
-
});
|
|
1931
2044
|
const cssText = style.cssText;
|
|
1932
2045
|
if (cssText.includes("var(")) {
|
|
1933
2046
|
if (isSafari) {
|
|
@@ -1961,6 +2074,13 @@
|
|
|
1961
2074
|
) {
|
|
1962
2075
|
handleEmptyShorthand("border", style, iterate);
|
|
1963
2076
|
}
|
|
2077
|
+
forEach(style, (property) => {
|
|
2078
|
+
const value = style.getPropertyValue(property).trim();
|
|
2079
|
+
if (!value) {
|
|
2080
|
+
return;
|
|
2081
|
+
}
|
|
2082
|
+
iterate(property, value);
|
|
2083
|
+
});
|
|
1964
2084
|
}
|
|
1965
2085
|
function handleEmptyShorthand(shorthand, style, iterate) {
|
|
1966
2086
|
const parentRule = style.parentRule;
|
|
@@ -2759,14 +2879,62 @@
|
|
|
2759
2879
|
async function getImageDetails(url) {
|
|
2760
2880
|
return new Promise(async (resolve, reject) => {
|
|
2761
2881
|
try {
|
|
2762
|
-
|
|
2882
|
+
let dataURL = url.startsWith("data:")
|
|
2763
2883
|
? url
|
|
2764
2884
|
: await getDataURL(url);
|
|
2765
2885
|
const blob =
|
|
2766
2886
|
tryConvertDataURLToBlobSync(dataURL) ??
|
|
2767
2887
|
(await loadAsBlob(url));
|
|
2768
2888
|
let image;
|
|
2889
|
+
let useViewBox = false;
|
|
2769
2890
|
if (dataURL.startsWith("data:image/svg+xml")) {
|
|
2891
|
+
const commaIndex = dataURL.indexOf(",");
|
|
2892
|
+
if (commaIndex >= 0) {
|
|
2893
|
+
let svgText = dataURL.slice(commaIndex + 1);
|
|
2894
|
+
const encoding = dataURL
|
|
2895
|
+
.slice(0, commaIndex)
|
|
2896
|
+
.split(";")[1];
|
|
2897
|
+
if (encoding === "base64") {
|
|
2898
|
+
if (svgText.includes("%")) {
|
|
2899
|
+
svgText = decodeURIComponent(svgText);
|
|
2900
|
+
}
|
|
2901
|
+
svgText = atob(svgText);
|
|
2902
|
+
} else if (svgText.startsWith("%3c")) {
|
|
2903
|
+
svgText = decodeURIComponent(svgText);
|
|
2904
|
+
}
|
|
2905
|
+
if (svgText.startsWith("<svg ")) {
|
|
2906
|
+
const closingIndex = svgText.indexOf(">");
|
|
2907
|
+
const svgOpening = svgText
|
|
2908
|
+
.slice(0, closingIndex + 1)
|
|
2909
|
+
.toLocaleLowerCase();
|
|
2910
|
+
if (
|
|
2911
|
+
svgOpening.includes("viewbox=") &&
|
|
2912
|
+
!svgOpening.includes("width=") &&
|
|
2913
|
+
!svgOpening.includes("height=")
|
|
2914
|
+
) {
|
|
2915
|
+
useViewBox = true;
|
|
2916
|
+
const viewboxIndex =
|
|
2917
|
+
svgOpening.indexOf("viewbox=");
|
|
2918
|
+
const quote = svgOpening[viewboxIndex + 8];
|
|
2919
|
+
const viewboxCloseIndex = svgOpening.indexOf(
|
|
2920
|
+
quote,
|
|
2921
|
+
viewboxIndex + 9
|
|
2922
|
+
);
|
|
2923
|
+
const viewBox = svgOpening
|
|
2924
|
+
.slice(viewboxIndex + 9, viewboxCloseIndex)
|
|
2925
|
+
.split(" ")
|
|
2926
|
+
.map((x) => parseFloat(x));
|
|
2927
|
+
if (
|
|
2928
|
+
viewBox.length === 4 &&
|
|
2929
|
+
!viewBox.some((x) => isNaN(x))
|
|
2930
|
+
) {
|
|
2931
|
+
const width = viewBox[2] - viewBox[0];
|
|
2932
|
+
const height = viewBox[3] - viewBox[1];
|
|
2933
|
+
dataURL = `data:image/svg+xml;base64,${btoa(`<svg width="${width}" height="${height}" ${svgText.slice(5)}`)}`;
|
|
2934
|
+
}
|
|
2935
|
+
}
|
|
2936
|
+
}
|
|
2937
|
+
}
|
|
2770
2938
|
image = await loadImage(dataURL);
|
|
2771
2939
|
} else {
|
|
2772
2940
|
image =
|
|
@@ -2780,6 +2948,7 @@
|
|
|
2780
2948
|
dataURL: analysis.isLarge ? "" : dataURL,
|
|
2781
2949
|
width: image.width,
|
|
2782
2950
|
height: image.height,
|
|
2951
|
+
useViewBox,
|
|
2783
2952
|
...analysis
|
|
2784
2953
|
});
|
|
2785
2954
|
});
|
|
@@ -2967,13 +3136,16 @@
|
|
|
2967
3136
|
}
|
|
2968
3137
|
document.addEventListener("securitypolicyviolation", onCSPError);
|
|
2969
3138
|
const objectURLs = new Set();
|
|
2970
|
-
function getFilteredImageURL({dataURL, width, height}, theme) {
|
|
3139
|
+
function getFilteredImageURL({dataURL, width, height, useViewBox}, theme) {
|
|
2971
3140
|
if (dataURL.startsWith("data:image/svg+xml")) {
|
|
2972
3141
|
dataURL = escapeXML(dataURL);
|
|
2973
3142
|
}
|
|
2974
3143
|
const matrix = getSVGFilterMatrixValue(theme);
|
|
3144
|
+
const size = useViewBox
|
|
3145
|
+
? `viewBox="0 0 ${width} ${height}"`
|
|
3146
|
+
: `width="${width}" height="${height}"`;
|
|
2975
3147
|
const svg = [
|
|
2976
|
-
`<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
3148
|
+
`<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" ${size}>`,
|
|
2977
3149
|
"<defs>",
|
|
2978
3150
|
'<filter id="darkreader-image-filter">',
|
|
2979
3151
|
`<feColorMatrix type="matrix" values="${matrix}" />`,
|
|
@@ -3016,7 +3188,11 @@
|
|
|
3016
3188
|
if (encoding !== "base64" || !mediaType) {
|
|
3017
3189
|
return null;
|
|
3018
3190
|
}
|
|
3019
|
-
|
|
3191
|
+
let base64Content = dataURL.substring(commaIndex + 1);
|
|
3192
|
+
if (base64Content.includes("%")) {
|
|
3193
|
+
base64Content = decodeURIComponent(base64Content);
|
|
3194
|
+
}
|
|
3195
|
+
const characters = atob(base64Content);
|
|
3020
3196
|
const bytes = new Uint8Array(characters.length);
|
|
3021
3197
|
for (let i = 0; i < characters.length; i++) {
|
|
3022
3198
|
bytes[i] = characters.charCodeAt(i);
|
|
@@ -3053,6 +3229,12 @@
|
|
|
3053
3229
|
function getPriority(ruleStyle, property) {
|
|
3054
3230
|
return Boolean(ruleStyle && ruleStyle.getPropertyPriority(property));
|
|
3055
3231
|
}
|
|
3232
|
+
const bgPropsToCopy = [
|
|
3233
|
+
"background-clip",
|
|
3234
|
+
"background-position",
|
|
3235
|
+
"background-repeat",
|
|
3236
|
+
"background-size"
|
|
3237
|
+
];
|
|
3056
3238
|
function getModifiableCSSDeclaration(
|
|
3057
3239
|
property,
|
|
3058
3240
|
value,
|
|
@@ -3123,6 +3305,8 @@
|
|
|
3123
3305
|
);
|
|
3124
3306
|
} else if (property.includes("shadow")) {
|
|
3125
3307
|
modifier = getShadowModifier(value);
|
|
3308
|
+
} else if (bgPropsToCopy.includes(property) && value !== "initial") {
|
|
3309
|
+
modifier = value;
|
|
3126
3310
|
}
|
|
3127
3311
|
if (!modifier) {
|
|
3128
3312
|
return null;
|
|
@@ -4234,9 +4418,7 @@
|
|
|
4234
4418
|
}
|
|
4235
4419
|
this.definedVars.add(varName);
|
|
4236
4420
|
const isColor = Boolean(
|
|
4237
|
-
value
|
|
4238
|
-
value.match(rawRGBCommaRegex) ||
|
|
4239
|
-
parseColorWithCache(value)
|
|
4421
|
+
getRGBValues(value) || parseColorWithCache(value)
|
|
4240
4422
|
);
|
|
4241
4423
|
if (isColor) {
|
|
4242
4424
|
this.unknownColorVars.add(varName);
|
|
@@ -4575,16 +4757,13 @@
|
|
|
4575
4757
|
function isTextColorProperty(property) {
|
|
4576
4758
|
return textColorProps.includes(property);
|
|
4577
4759
|
}
|
|
4578
|
-
const rawRGBSpaceRegex =
|
|
4579
|
-
/^(\d{1,3})\s+(\d{1,3})\s+(\d{1,3})\s*(\/\s*\d+\.?\d*)?$/;
|
|
4580
|
-
const rawRGBCommaRegex = /^(\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})$/;
|
|
4581
4760
|
function parseRawColorValue(input) {
|
|
4582
|
-
const
|
|
4583
|
-
|
|
4584
|
-
|
|
4585
|
-
|
|
4586
|
-
|
|
4587
|
-
|
|
4761
|
+
const v = getRGBValues(input);
|
|
4762
|
+
if (v) {
|
|
4763
|
+
const color =
|
|
4764
|
+
v[3] < 1
|
|
4765
|
+
? `rgb(${v[0]} ${v[1]} ${v[2]} / ${v[3]})`
|
|
4766
|
+
: `rgb(${v[0]} ${v[1]} ${v[2]})`;
|
|
4588
4767
|
return {isRaw: true, color};
|
|
4589
4768
|
}
|
|
4590
4769
|
return {isRaw: false, color: input};
|
|
@@ -4597,7 +4776,9 @@
|
|
|
4597
4776
|
if (isRaw) {
|
|
4598
4777
|
const outputInRGB = parseColorWithCache(outputColor);
|
|
4599
4778
|
return outputInRGB
|
|
4600
|
-
?
|
|
4779
|
+
? Number.isNaN(outputInRGB.a) || outputInRGB.a === 1
|
|
4780
|
+
? `${outputInRGB.r}, ${outputInRGB.g}, ${outputInRGB.b}`
|
|
4781
|
+
: `${outputInRGB.r}, ${outputInRGB.g}, ${outputInRGB.b}, ${outputInRGB.a}`
|
|
4601
4782
|
: outputColor;
|
|
4602
4783
|
}
|
|
4603
4784
|
return outputColor;
|
|
@@ -5629,8 +5810,8 @@
|
|
|
5629
5810
|
}
|
|
5630
5811
|
const shouldAnalyze = Boolean(
|
|
5631
5812
|
svg &&
|
|
5632
|
-
|
|
5633
|
-
|
|
5813
|
+
(svg.getAttribute("class")?.includes("logo") ||
|
|
5814
|
+
svg.parentElement?.getAttribute("class")?.includes("logo"))
|
|
5634
5815
|
);
|
|
5635
5816
|
svgAnalysisConditionCache.set(svg, shouldAnalyze);
|
|
5636
5817
|
return shouldAnalyze;
|
|
@@ -5673,6 +5854,7 @@
|
|
|
5673
5854
|
svgNodesRoots.set(svgElement, root);
|
|
5674
5855
|
return root;
|
|
5675
5856
|
}
|
|
5857
|
+
const inlineStringValueCache = new Map();
|
|
5676
5858
|
function overrideInlineStyle(
|
|
5677
5859
|
element,
|
|
5678
5860
|
theme,
|
|
@@ -5700,6 +5882,13 @@
|
|
|
5700
5882
|
}
|
|
5701
5883
|
const unsetProps = new Set(Object.keys(overrides));
|
|
5702
5884
|
function setCustomProp(targetCSSProp, modifierCSSProp, cssVal) {
|
|
5885
|
+
const cachedStringValue = inlineStringValueCache
|
|
5886
|
+
.get(modifierCSSProp)
|
|
5887
|
+
?.get(cssVal);
|
|
5888
|
+
if (cachedStringValue) {
|
|
5889
|
+
setStaticValue(cachedStringValue);
|
|
5890
|
+
return;
|
|
5891
|
+
}
|
|
5703
5892
|
const mod = getModifiableCSSDeclaration(
|
|
5704
5893
|
modifierCSSProp,
|
|
5705
5894
|
cssVal,
|
|
@@ -5766,6 +5955,10 @@
|
|
|
5766
5955
|
typeof mod.value === "function" ? mod.value(theme) : mod.value;
|
|
5767
5956
|
if (typeof value === "string") {
|
|
5768
5957
|
setStaticValue(value);
|
|
5958
|
+
if (!inlineStringValueCache.has(modifierCSSProp)) {
|
|
5959
|
+
inlineStringValueCache.set(modifierCSSProp, new Map());
|
|
5960
|
+
}
|
|
5961
|
+
inlineStringValueCache.get(modifierCSSProp).set(cssVal, value);
|
|
5769
5962
|
} else if (value instanceof Promise) {
|
|
5770
5963
|
setAsyncValue(value, cssVal);
|
|
5771
5964
|
} else if (typeof value === "object") {
|
|
@@ -5852,13 +6045,16 @@
|
|
|
5852
6045
|
value.match(/^[0-9a-f]{6}$/i)
|
|
5853
6046
|
) {
|
|
5854
6047
|
value = `#${value}`;
|
|
6048
|
+
} else if (value.match(/^#?[0-9a-f]{4}$/i)) {
|
|
6049
|
+
const hex = value.startsWith("#") ? value.substring(1) : value;
|
|
6050
|
+
value = `#${hex}00`;
|
|
5855
6051
|
}
|
|
5856
6052
|
setCustomProp("color", "color", value);
|
|
5857
6053
|
}
|
|
5858
6054
|
if (isSVGElement) {
|
|
5859
6055
|
if (element.hasAttribute("fill")) {
|
|
5860
6056
|
const value = element.getAttribute("fill");
|
|
5861
|
-
if (value !== "none") {
|
|
6057
|
+
if (value !== "none" && value !== "currentColor") {
|
|
5862
6058
|
if (!(element instanceof SVGTextElement)) {
|
|
5863
6059
|
const handleSVGElement = () => {
|
|
5864
6060
|
let isSVGSmall = false;
|
|
@@ -6141,17 +6337,28 @@
|
|
|
6141
6337
|
}
|
|
6142
6338
|
|
|
6143
6339
|
const STYLE_SELECTOR = 'style, link[rel*="stylesheet" i]:not([disabled])';
|
|
6144
|
-
|
|
6145
|
-
|
|
6340
|
+
let ignoredCSSURLPatterns = [];
|
|
6341
|
+
function setIgnoredCSSURLs(patterns) {
|
|
6342
|
+
ignoredCSSURLPatterns = patterns || [];
|
|
6343
|
+
}
|
|
6344
|
+
function shouldIgnoreCSSURL(url) {
|
|
6345
|
+
if (!url || ignoredCSSURLPatterns.length === 0) {
|
|
6146
6346
|
return false;
|
|
6147
6347
|
}
|
|
6148
|
-
|
|
6149
|
-
|
|
6150
|
-
|
|
6151
|
-
|
|
6152
|
-
|
|
6153
|
-
|
|
6348
|
+
for (const pattern of ignoredCSSURLPatterns) {
|
|
6349
|
+
if (pattern.startsWith("^")) {
|
|
6350
|
+
if (url.startsWith(pattern.slice(1))) {
|
|
6351
|
+
return true;
|
|
6352
|
+
}
|
|
6353
|
+
} else if (pattern.endsWith("$")) {
|
|
6354
|
+
if (url.endsWith(pattern.slice(0, -1))) {
|
|
6355
|
+
return true;
|
|
6356
|
+
}
|
|
6357
|
+
} else if (url.includes(pattern)) {
|
|
6358
|
+
return true;
|
|
6359
|
+
}
|
|
6154
6360
|
}
|
|
6361
|
+
return false;
|
|
6155
6362
|
}
|
|
6156
6363
|
const hostsBreakingOnSVGStyleOverride = [
|
|
6157
6364
|
"account.containerstore.com",
|
|
@@ -6173,7 +6380,7 @@
|
|
|
6173
6380
|
(isFirefox
|
|
6174
6381
|
? !element.href.startsWith("moz-extension://")
|
|
6175
6382
|
: true) &&
|
|
6176
|
-
!
|
|
6383
|
+
!shouldIgnoreCSSURL(element.href))) &&
|
|
6177
6384
|
!element.classList.contains("darkreader") &&
|
|
6178
6385
|
!ignoredMedia.includes(element.media.toLowerCase()) &&
|
|
6179
6386
|
!element.classList.contains("stylus")
|
|
@@ -6190,7 +6397,7 @@
|
|
|
6190
6397
|
forEach(node.querySelectorAll(STYLE_SELECTOR), (style) =>
|
|
6191
6398
|
getManageableStyles(style, results, false)
|
|
6192
6399
|
);
|
|
6193
|
-
if (deep) {
|
|
6400
|
+
if (deep && (node.children?.length > 0 || node.shadowRoot)) {
|
|
6194
6401
|
iterateShadowHosts(node, (host) =>
|
|
6195
6402
|
getManageableStyles(host.shadowRoot, results, false)
|
|
6196
6403
|
);
|
|
@@ -7358,10 +7565,23 @@
|
|
|
7358
7565
|
removedStyles,
|
|
7359
7566
|
movedStyles
|
|
7360
7567
|
});
|
|
7568
|
+
const potentialHosts = new Set();
|
|
7361
7569
|
additions.forEach((n) => {
|
|
7570
|
+
if (n.parentElement) {
|
|
7571
|
+
potentialHosts.add(n.parentElement);
|
|
7572
|
+
}
|
|
7573
|
+
if (n.previousElementSibling) {
|
|
7574
|
+
potentialHosts.add(n.previousElementSibling);
|
|
7575
|
+
}
|
|
7362
7576
|
deepObserve(n);
|
|
7363
7577
|
collectUndefinedElements(n);
|
|
7364
7578
|
});
|
|
7579
|
+
potentialHosts.forEach((el) => {
|
|
7580
|
+
if (el.shadowRoot && !observedRoots.has(el)) {
|
|
7581
|
+
subscribeForShadowRootChanges(el);
|
|
7582
|
+
deepObserve(el.shadowRoot);
|
|
7583
|
+
}
|
|
7584
|
+
});
|
|
7365
7585
|
additions.forEach(
|
|
7366
7586
|
(node) => isCustomElement(node) && recordUndefinedElement(node)
|
|
7367
7587
|
);
|
|
@@ -7475,6 +7695,14 @@
|
|
|
7475
7695
|
});
|
|
7476
7696
|
document.addEventListener("__darkreader__isDefined", handleIsDefined);
|
|
7477
7697
|
collectUndefinedElements(document);
|
|
7698
|
+
addDOMReadyListener(() => {
|
|
7699
|
+
forEach(document.body.children, (el) => {
|
|
7700
|
+
if (el.shadowRoot && !observedRoots.has(el)) {
|
|
7701
|
+
subscribeForShadowRootChanges(el);
|
|
7702
|
+
deepObserve(el.shadowRoot);
|
|
7703
|
+
}
|
|
7704
|
+
});
|
|
7705
|
+
});
|
|
7478
7706
|
}
|
|
7479
7707
|
function resetObservers() {
|
|
7480
7708
|
observers.forEach((o) => o.disconnect());
|
|
@@ -8182,9 +8410,13 @@
|
|
|
8182
8410
|
ignoredInlineSelectors = Array.isArray(fixes.ignoreInlineStyle)
|
|
8183
8411
|
? fixes.ignoreInlineStyle
|
|
8184
8412
|
: [];
|
|
8413
|
+
setIgnoredCSSURLs(
|
|
8414
|
+
Array.isArray(fixes.ignoreCSSUrl) ? fixes.ignoreCSSUrl : []
|
|
8415
|
+
);
|
|
8185
8416
|
} else {
|
|
8186
8417
|
ignoredImageAnalysisSelectors = [];
|
|
8187
8418
|
ignoredInlineSelectors = [];
|
|
8419
|
+
setIgnoredCSSURLs([]);
|
|
8188
8420
|
}
|
|
8189
8421
|
if (theme.immediateModify) {
|
|
8190
8422
|
setIsDOMReady(() => {
|