| 1 |
/* |
| 2 |
* ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development"). |
| 3 |
* This devtool is neither made for production nor for readable output files. |
| 4 |
* It uses "eval()" calls to create a separate source file in the browser devtools. |
| 5 |
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/) |
| 6 |
* or disable the default devtool with "devtool: false". |
| 7 |
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/). |
| 8 |
*/ |
| 9 |
/******/ (() => { // webpackBootstrap |
| 10 |
/******/ "use strict"; |
| 11 |
/******/ var __webpack_modules__ = ({ |
| 12 |
|
| 13 |
/***/ "./index.js": |
| 14 |
/*!******************!*\ |
| 15 |
!*** ./index.js ***! |
| 16 |
\******************/ |
| 17 |
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { |
| 18 |
|
| 19 |
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _src_main__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./src/main */ \"./src/main.js\");\n\nwindow.AdminifyDarkMode = {\n enable: config => (0,_src_main__WEBPACK_IMPORTED_MODULE_0__.run)(config),\n disable: () => (0,_src_main__WEBPACK_IMPORTED_MODULE_0__.remove)()\n};\n\n//# sourceURL=webpack://dark-mode/./index.js?"); |
| 20 |
|
| 21 |
/***/ }), |
| 22 |
|
| 23 |
/***/ "./src/default.js": |
| 24 |
/*!************************!*\ |
| 25 |
!*** ./src/default.js ***! |
| 26 |
\************************/ |
| 27 |
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { |
| 28 |
|
| 29 |
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ DEFAULT_COLORS: () => (/* binding */ DEFAULT_COLORS),\n/* harmony export */ DEFAULT_COLORSCHEME: () => (/* binding */ DEFAULT_COLORSCHEME),\n/* harmony export */ DEFAULT_SETTINGS: () => (/* binding */ DEFAULT_SETTINGS),\n/* harmony export */ DEFAULT_THEME: () => (/* binding */ DEFAULT_THEME)\n/* harmony export */ });\n// import { ThemeEngine } from \"./generators/theme-engines\";\n// import { isMacOS, isWindows, isCSSColorSchemePropSupported } from \"./utils/platform\";\n// import { AutomationMode } from \"./utils/automation\";\n\nconst DEFAULT_COLORS = {\n darkScheme: {\n // background: \"#181a1b\",\n // text: \"#e8e6e3\",\n\n background: \"#131516\",\n text: \"#d8d4cf\"\n\n // background: \"black\",\n // text: \"white\",\n },\n lightScheme: {\n // background: \"#dcdad7\",\n // text: \"#181a1b\",\n\n background: \"#004daa\",\n text: \"#e8e6e3\"\n }\n};\nconst DEFAULT_THEME = {\n mode: 1,\n brightness: 100,\n contrast: 100,\n grayscale: 0,\n sepia: 0,\n imgGrayscale: false,\n // boolean true | flase\n imgGrayscalePercent: \"100%\",\n // (min:0% | max:100% )\n videoGrayscale: false,\n videoGrayscalePercent: \"100%\",\n useFont: false,\n // fontFamily: isMacOS ? \"Helvetica Neue\" : isWindows ? \"Segoe UI\" : \"Open Sans\",\n fontFamily: \"Open Sans\",\n textStroke: 0,\n engine: \"\",\n //ThemeEngine.dynamicTheme,\n stylesheet: \"\",\n darkSchemeBackgroundColor: DEFAULT_COLORS.darkScheme.background,\n darkSchemeTextColor: DEFAULT_COLORS.darkScheme.text,\n lightSchemeBackgroundColor: DEFAULT_COLORS.lightScheme.background,\n lightSchemeTextColor: DEFAULT_COLORS.lightScheme.text,\n // scrollbarColor: isMacOS ? \"\" : \"auto\",\n scrollbarColor: \"auto\",\n selectionColor: \"auto\",\n styleSystemControls: false,\n lightColorScheme: \"Default\",\n darkColorScheme: \"Default\",\n immediateModify: false\n};\nconst DEFAULT_COLORSCHEME = {\n light: {\n Default: {\n backgroundColor: DEFAULT_COLORS.lightScheme.background,\n textColor: DEFAULT_COLORS.lightScheme.text\n }\n },\n dark: {\n Default: {\n backgroundColor: DEFAULT_COLORS.darkScheme.background,\n textColor: DEFAULT_COLORS.darkScheme.text\n }\n }\n};\nconst DEFAULT_SETTINGS = {\n enabled: true,\n fetchNews: true,\n theme: DEFAULT_THEME,\n presets: [],\n customThemes: [],\n siteList: [],\n siteListEnabled: [],\n applyToListedOnly: false,\n changeBrowserTheme: false,\n syncSettings: true,\n syncSitesFixes: false,\n automation: {\n enabled: false,\n mode: \"\",\n //AutomationMode.NONE,\n behavior: \"OnOff\"\n },\n time: {\n activation: \"18:00\",\n deactivation: \"9:00\"\n },\n location: {\n latitude: null,\n longitude: null\n },\n previewNewDesign: false,\n enableForPDF: true,\n enableForProtectedPages: false,\n enableContextMenus: false,\n detectDarkTheme: false\n};\n\n//# sourceURL=webpack://dark-mode/./src/default.js?"); |
| 30 |
|
| 31 |
/***/ }), |
| 32 |
|
| 33 |
/***/ "./src/generators/css-filter.js": |
| 34 |
/*!**************************************!*\ |
| 35 |
!*** ./src/generators/css-filter.js ***! |
| 36 |
\**************************************/ |
| 37 |
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { |
| 38 |
|
| 39 |
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ FilterMode: () => (/* binding */ FilterMode),\n/* harmony export */ cssFilterStyleSheetTemplate: () => (/* binding */ cssFilterStyleSheetTemplate),\n/* harmony export */ getCSSFilterValue: () => (/* binding */ getCSSFilterValue),\n/* harmony export */ getInversionFixesFor: () => (/* binding */ getInversionFixesFor),\n/* harmony export */ hasFirefoxNewRootBehavior: () => (/* binding */ hasFirefoxNewRootBehavior),\n/* harmony export */ hasPatchForChromiumIssue501582: () => (/* binding */ hasPatchForChromiumIssue501582)\n/* harmony export */ });\n/* harmony import */ var _utils_matrix__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./utils/matrix */ \"./src/generators/utils/matrix.js\");\n/* harmony import */ var _utils_parse__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./utils/parse */ \"./src/generators/utils/parse.js\");\n/* harmony import */ var _utils_text__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/text */ \"./src/utils/text.js\");\n/* harmony import */ var _utils_url__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/url */ \"./src/utils/url.js\");\n/* harmony import */ var _text_style__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./text-style */ \"./src/generators/text-style.js\");\n/* harmony import */ var _utils_platform__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../utils/platform */ \"./src/utils/platform.js\");\n\n\n\n\n\n\nlet FilterMode;\n(function (FilterMode) {\n FilterMode[FilterMode[\"light\"] = 0] = \"light\";\n FilterMode[FilterMode[\"dark\"] = 1] = \"dark\";\n})(FilterMode || (FilterMode = {}));\n\n/**\n * This checks if the current chromium version has the patch in it.\n * As of Chromium v81.0.4035.0 this has been the situation\n *\n * Bug report: https://bugs.chromium.org/p/chromium/issues/detail?id=501582\n * Patch: https://chromium-review.googlesource.com/c/chromium/src/+/1979258\n */\nfunction hasPatchForChromiumIssue501582() {\n return __CHROMIUM_MV3__ || Boolean(__CHROMIUM_MV2__ && (0,_utils_platform__WEBPACK_IMPORTED_MODULE_5__.compareChromeVersions)(_utils_platform__WEBPACK_IMPORTED_MODULE_5__.chromiumVersion, \"81.0.4035.0\") >= 0);\n}\n\n/**\n * Since Firefox v102.0, they have changed to the new root behavior.\n * This was already the case for Chromium v81.0.4035.0 and Firefox now\n * switched over as well.\n */\nfunction hasFirefoxNewRootBehavior() {\n return Boolean(_utils_platform__WEBPACK_IMPORTED_MODULE_5__.isFirefox && (0,_utils_platform__WEBPACK_IMPORTED_MODULE_5__.compareChromeVersions)(_utils_platform__WEBPACK_IMPORTED_MODULE_5__.firefoxVersion, \"102.0\") >= 0);\n}\n\n// export default function createCSSFilterStyleSheet(config, url, isTopFrame, fixes, index) {\n// const filterValue = getCSSFilterValue(config);\n// const reverseFilterValue = \"invert(100%) hue-rotate(180deg)\";\n// return cssFilterStyleSheetTemplate(\n// filterValue,\n// reverseFilterValue,\n// config,\n// url,\n// isTopFrame,\n// fixes,\n// index\n// );\n// }\n\nfunction cssFilterStyleSheetTemplate(filterValue, reverseFilterValue, config, url, isTopFrame, fixes, index) {\n const fix = getInversionFixesFor(url, fixes, index);\n const lines = [];\n lines.push(\"@media screen {\");\n\n // Add leading rule\n if (filterValue && isTopFrame) {\n lines.push(\"\");\n lines.push(\"/* Leading rule */\");\n lines.push(createLeadingRule(filterValue));\n }\n if (config.mode === FilterMode.dark) {\n // Add reverse rule\n lines.push(\"\");\n lines.push(\"/* Reverse rule */\");\n lines.push(createReverseRule(reverseFilterValue, fix));\n }\n if (config.useFont || config.textStroke > 0) {\n // Add text rule\n lines.push(\"\");\n lines.push(\"/* Font */\");\n lines.push((0,_text_style__WEBPACK_IMPORTED_MODULE_4__.createTextStyle)(config));\n }\n\n // Fix bad font hinting after inversion\n lines.push(\"\");\n lines.push(\"/* Text contrast */\");\n lines.push(\"html {\");\n lines.push(\" text-shadow: 0 0 0 !important;\");\n lines.push(\"}\");\n\n // Full screen fix\n lines.push(\"\");\n lines.push(\"/* Full screen */\");\n [\":-webkit-full-screen\", \":-moz-full-screen\", \":fullscreen\"].forEach(fullScreen => {\n lines.push(`${fullScreen}, ${fullScreen} * {`);\n lines.push(\" -webkit-filter: none !important;\");\n lines.push(\" filter: none !important;\");\n lines.push(\"}\");\n });\n if (isTopFrame) {\n const light = [255, 255, 255];\n // If browser affected by Chromium Issue 501582, set dark background on html\n // Or if browser is Firefox v102+\n const bgColor = !hasPatchForChromiumIssue501582() && !hasFirefoxNewRootBehavior() && config.mode === FilterMode.dark ? (0,_utils_matrix__WEBPACK_IMPORTED_MODULE_0__.applyColorMatrix)(light, (0,_utils_matrix__WEBPACK_IMPORTED_MODULE_0__.createFilterMatrix)(config)).map(Math.round) : light;\n lines.push(\"\");\n lines.push(\"/* Page background */\");\n lines.push(\"html {\");\n lines.push(` background: rgb(${bgColor.join(\",\")}) !important;`);\n lines.push(\"}\");\n }\n if (fix.css && fix.css.length > 0 && config.mode === FilterMode.dark) {\n lines.push(\"\");\n lines.push(\"/* Custom rules */\");\n lines.push(fix.css);\n }\n lines.push(\"\");\n lines.push(\"}\");\n return lines.join(\"\\n\");\n}\nfunction getCSSFilterValue(config) {\n const filters = [];\n if (config.mode === FilterMode.dark) {\n filters.push(\"invert(100%) hue-rotate(180deg)\");\n }\n if (config.brightness !== 100) {\n filters.push(`brightness(${config.brightness}%)`);\n }\n if (config.contrast !== 100) {\n filters.push(`contrast(${config.contrast}%)`);\n }\n if (config.grayscale !== 0) {\n filters.push(`grayscale(${config.grayscale}%)`);\n }\n if (config.sepia !== 0) {\n filters.push(`sepia(${config.sepia}%)`);\n }\n if (filters.length === 0) {\n return null;\n }\n return filters.join(\" \");\n}\nfunction createLeadingRule(filterValue) {\n return [\"html {\", ` -webkit-filter: ${filterValue} !important;`, ` filter: ${filterValue} !important;`, \"}\"].join(\"\\n\");\n}\nfunction joinSelectors(selectors) {\n return selectors.map(s => s.replace(/\\,$/, \"\")).join(\",\\n\");\n}\nfunction createReverseRule(reverseFilterValue, fix) {\n const lines = [];\n if (fix.invert.length > 0) {\n lines.push(`${joinSelectors(fix.invert)} {`);\n lines.push(` -webkit-filter: ${reverseFilterValue} !important;`);\n lines.push(` filter: ${reverseFilterValue} !important;`);\n lines.push(\"}\");\n }\n if (fix.noinvert.length > 0) {\n lines.push(`${joinSelectors(fix.noinvert)} {`);\n lines.push(\" -webkit-filter: none !important;\");\n lines.push(\" filter: none !important;\");\n lines.push(\"}\");\n }\n if (fix.removebg.length > 0) {\n lines.push(`${joinSelectors(fix.removebg)} {`);\n lines.push(\" background: white !important;\");\n lines.push(\"}\");\n }\n return lines.join(\"\\n\");\n}\n\n/**\n * Returns fixes for a given URL.\n * If no matches found, common fixes will be returned.\n * @param url Site URL.\n * @param inversionFixes List of inversion fixes.\n */\nfunction getInversionFixesFor(url, fixes, index) {\n const inversionFixes = (0,_utils_parse__WEBPACK_IMPORTED_MODULE_1__.getSitesFixesFor)(url, fixes, index, {\n commands: Object.keys(inversionFixesCommands),\n getCommandPropName: command => inversionFixesCommands[command],\n parseCommandValue: (command, value) => {\n if (command === \"CSS\") {\n return value.trim();\n }\n return (0,_utils_text__WEBPACK_IMPORTED_MODULE_2__.parseArray)(value);\n }\n });\n const common = {\n url: inversionFixes[0].url,\n invert: inversionFixes[0].invert || [],\n noinvert: inversionFixes[0].noinvert || [],\n removebg: inversionFixes[0].removebg || [],\n css: inversionFixes[0].css || \"\"\n };\n if (url) {\n // Search for match with given URL\n const matches = inversionFixes.slice(1).filter(s => (0,_utils_url__WEBPACK_IMPORTED_MODULE_3__.isURLInList)(url, s.url)).sort((a, b) => b.url[0].length - a.url[0].length);\n if (matches.length > 0) {\n const found = matches[0];\n return {\n url: found.url,\n invert: common.invert.concat(found.invert || []),\n noinvert: common.noinvert.concat(found.noinvert || []),\n removebg: common.removebg.concat(found.removebg || []),\n css: [common.css, found.css].filter(s => s).join(\"\\n\")\n };\n }\n }\n return common;\n}\nconst inversionFixesCommands = {\n INVERT: \"invert\",\n \"NO INVERT\": \"noinvert\",\n \"REMOVE BG\": \"removebg\",\n CSS: \"css\"\n};\n\n// export function parseInversionFixes(text) {\n// return parseSitesFixesConfig(text, {\n// commands: Object.keys(inversionFixesCommands),\n// getCommandPropName: (command) => inversionFixesCommands[command],\n// parseCommandValue: (command, value) => {\n// if (command === \"CSS\") {\n// return value.trim();\n// }\n// return parseArray(value);\n// },\n// });\n// }\n\n// export function formatInversionFixes(inversionFixes) {\n// const fixes = inversionFixes.slice().sort((a, b) => compareURLPatterns(a.url[0], b.url[0]));\n\n// return formatSitesFixesConfig(fixes, {\n// props: Object.values(inversionFixesCommands),\n// getPropCommandName: (prop) =>\n// Object.entries(inversionFixesCommands).find(([, p]) => p === prop)[0],\n// formatPropValue: (prop, value) => {\n// if (prop === \"css\") {\n// return value.trim().replace(/\\n+/g, \"\\n\");\n// }\n// return formatArray(value).trim();\n// },\n// shouldIgnoreProp: (prop, value) => {\n// if (prop === \"css\") {\n// return !value;\n// }\n// return !(Array.isArray(value) && value.length > 0);\n// },\n// });\n// }\n\n//# sourceURL=webpack://dark-mode/./src/generators/css-filter.js?"); |
| 40 |
|
| 41 |
/***/ }), |
| 42 |
|
| 43 |
/***/ "./src/generators/modify-colors.js": |
| 44 |
/*!*****************************************!*\ |
| 45 |
!*** ./src/generators/modify-colors.js ***! |
| 46 |
\*****************************************/ |
| 47 |
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { |
| 48 |
|
| 49 |
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ clearColorModificationCache: () => (/* binding */ clearColorModificationCache),\n/* harmony export */ modifyBackgroundColor: () => (/* binding */ modifyBackgroundColor),\n/* harmony export */ modifyBorderColor: () => (/* binding */ modifyBorderColor),\n/* harmony export */ modifyColor: () => (/* binding */ modifyColor),\n/* harmony export */ modifyForegroundColor: () => (/* binding */ modifyForegroundColor),\n/* harmony export */ modifyGradientColor: () => (/* binding */ modifyGradientColor),\n/* harmony export */ modifyShadowColor: () => (/* binding */ modifyShadowColor)\n/* harmony export */ });\n/* harmony import */ var _utils_color__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils/color */ \"./src/utils/color.js\");\n/* harmony import */ var _utils_math__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../utils/math */ \"./src/utils/math.js\");\n/* harmony import */ var _utils_matrix__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./utils/matrix */ \"./src/generators/utils/matrix.js\");\n\n\n\nfunction getBgPole(theme) {\n const isDarkScheme = theme.mode === 1;\n const prop = isDarkScheme ? \"darkSchemeBackgroundColor\" : \"lightSchemeBackgroundColor\";\n return theme[prop];\n}\nfunction getFgPole(theme) {\n const isDarkScheme = theme.mode === 1;\n const prop = isDarkScheme ? \"darkSchemeTextColor\" : \"lightSchemeTextColor\";\n return theme[prop];\n}\nconst colorModificationCache = new Map();\nfunction clearColorModificationCache() {\n colorModificationCache.clear();\n}\nconst rgbCacheKeys = [\"r\", \"g\", \"b\", \"a\"];\nconst themeCacheKeys = [\"mode\", \"brightness\", \"contrast\", \"grayscale\", \"sepia\", \"darkSchemeBackgroundColor\", \"darkSchemeTextColor\", \"lightSchemeBackgroundColor\", \"lightSchemeTextColor\"];\nfunction getCacheId(rgb, theme) {\n let resultId = \"\";\n rgbCacheKeys.forEach(key => {\n resultId += `${rgb[key]};`;\n });\n themeCacheKeys.forEach(key => {\n resultId += `${theme[key]};`;\n });\n return resultId;\n}\nfunction modifyColorWithCache(rgb, theme, modifyHSL, poleColor, anotherPoleColor) {\n let fnCache;\n if (colorModificationCache.has(modifyHSL)) {\n fnCache = colorModificationCache.get(modifyHSL);\n } else {\n fnCache = new Map();\n colorModificationCache.set(modifyHSL, fnCache);\n }\n const id = getCacheId(rgb, theme);\n if (fnCache.has(id)) {\n return fnCache.get(id);\n }\n const hsl = (0,_utils_color__WEBPACK_IMPORTED_MODULE_0__.rgbToHSL)(rgb);\n const pole = poleColor == null ? null : (0,_utils_color__WEBPACK_IMPORTED_MODULE_0__.parseToHSLWithCache)(poleColor);\n const anotherPole = anotherPoleColor == null ? null : (0,_utils_color__WEBPACK_IMPORTED_MODULE_0__.parseToHSLWithCache)(anotherPoleColor);\n const modified = modifyHSL(hsl, pole, anotherPole);\n const {\n r,\n g,\n b,\n a\n } = (0,_utils_color__WEBPACK_IMPORTED_MODULE_0__.hslToRGB)(modified);\n const matrix = (0,_utils_matrix__WEBPACK_IMPORTED_MODULE_2__.createFilterMatrix)(theme);\n const [rf, gf, bf] = (0,_utils_matrix__WEBPACK_IMPORTED_MODULE_2__.applyColorMatrix)([r, g, b], matrix);\n const color = a === 1 ? (0,_utils_color__WEBPACK_IMPORTED_MODULE_0__.rgbToHexString)({\n r: rf,\n g: gf,\n b: bf\n }) : (0,_utils_color__WEBPACK_IMPORTED_MODULE_0__.rgbToString)({\n r: rf,\n g: gf,\n b: bf,\n a\n });\n fnCache.set(id, color);\n return color;\n}\nfunction noopHSL(hsl) {\n return hsl;\n}\nfunction modifyColor(rgb, theme) {\n return modifyColorWithCache(rgb, theme, noopHSL);\n}\nfunction modifyLightSchemeColor(rgb, theme) {\n const poleBg = getBgPole(theme);\n const poleFg = getFgPole(theme);\n return modifyColorWithCache(rgb, theme, modifyLightModeHSL, poleFg, poleBg);\n}\nfunction modifyLightModeHSL({\n h,\n s,\n l,\n a\n}, poleFg, poleBg) {\n const isDark = l < 0.5;\n let isNeutral;\n if (isDark) {\n isNeutral = l < 0.2 || s < 0.12;\n } else {\n const isBlue = h > 200 && h < 280;\n isNeutral = s < 0.24 || l > 0.8 && isBlue;\n }\n let hx = h;\n let sx = l;\n if (isNeutral) {\n if (isDark) {\n hx = poleFg.h;\n sx = poleFg.s;\n } else {\n hx = poleBg.h;\n sx = poleBg.s;\n }\n }\n const lx = (0,_utils_math__WEBPACK_IMPORTED_MODULE_1__.scale)(l, 0, 1, poleFg.l, poleBg.l);\n return {\n h: hx,\n s: sx,\n l: lx,\n a\n };\n}\nconst MAX_BG_LIGHTNESS = 0.4;\nfunction modifyBgHSL({\n h,\n s,\n l,\n a\n}, pole) {\n const isDark = l < 0.5;\n const isBlue = h > 200 && h < 280;\n const isNeutral = s < 0.12 || l > 0.8 && isBlue;\n if (isDark) {\n const lx = (0,_utils_math__WEBPACK_IMPORTED_MODULE_1__.scale)(l, 0, 0.5, 0, MAX_BG_LIGHTNESS);\n if (isNeutral) {\n const hx = pole.h;\n const sx = pole.s;\n return {\n h: hx,\n s: sx,\n l: lx,\n a\n };\n }\n return {\n h,\n s,\n l: lx,\n a\n };\n }\n let lx = (0,_utils_math__WEBPACK_IMPORTED_MODULE_1__.scale)(l, 0.5, 1, MAX_BG_LIGHTNESS, pole.l);\n if (isNeutral) {\n const hx = pole.h;\n const sx = pole.s;\n return {\n h: hx,\n s: sx,\n l: lx,\n a\n };\n }\n let hx = h;\n const isYellow = h > 60 && h < 180;\n if (isYellow) {\n const isCloserToGreen = h > 120;\n if (isCloserToGreen) {\n hx = (0,_utils_math__WEBPACK_IMPORTED_MODULE_1__.scale)(h, 120, 180, 135, 180);\n } else {\n hx = (0,_utils_math__WEBPACK_IMPORTED_MODULE_1__.scale)(h, 60, 120, 60, 105);\n }\n }\n\n // Lower the lightness, if the resulting\n // hue is in lower yellow spectrum.\n if (hx > 40 && hx < 80) {\n lx *= 0.75;\n }\n return {\n h: hx,\n s,\n l: lx,\n a\n };\n}\nfunction modifyBackgroundColor(rgb, theme) {\n if (theme.mode === 0) {\n return modifyLightSchemeColor(rgb, theme);\n }\n const pole = getBgPole(theme);\n return modifyColorWithCache(rgb, {\n ...theme,\n mode: 0\n }, modifyBgHSL, pole);\n}\nconst MIN_FG_LIGHTNESS = 0.55;\nfunction modifyBlueFgHue(hue) {\n return (0,_utils_math__WEBPACK_IMPORTED_MODULE_1__.scale)(hue, 205, 245, 205, 220);\n}\nfunction modifyFgHSL({\n h,\n s,\n l,\n a\n}, pole) {\n const isLight = l > 0.5;\n const isNeutral = l < 0.2 || s < 0.24;\n const isBlue = !isNeutral && h > 205 && h < 245;\n if (isLight) {\n const lx = (0,_utils_math__WEBPACK_IMPORTED_MODULE_1__.scale)(l, 0.5, 1, MIN_FG_LIGHTNESS, pole.l);\n if (isNeutral) {\n const hx = pole.h;\n const sx = pole.s;\n return {\n h: hx,\n s: sx,\n l: lx,\n a\n };\n }\n let hx = h;\n if (isBlue) {\n hx = modifyBlueFgHue(h);\n }\n return {\n h: hx,\n s,\n l: lx,\n a\n };\n }\n if (isNeutral) {\n const hx = pole.h;\n const sx = pole.s;\n const lx = (0,_utils_math__WEBPACK_IMPORTED_MODULE_1__.scale)(l, 0, 0.5, pole.l, MIN_FG_LIGHTNESS);\n return {\n h: hx,\n s: sx,\n l: lx,\n a\n };\n }\n let hx = h;\n let lx;\n if (isBlue) {\n hx = modifyBlueFgHue(h);\n lx = (0,_utils_math__WEBPACK_IMPORTED_MODULE_1__.scale)(l, 0, 0.5, pole.l, Math.min(1, MIN_FG_LIGHTNESS + 0.05));\n } else {\n lx = (0,_utils_math__WEBPACK_IMPORTED_MODULE_1__.scale)(l, 0, 0.5, pole.l, MIN_FG_LIGHTNESS);\n }\n return {\n h: hx,\n s,\n l: lx,\n a\n };\n}\nfunction modifyForegroundColor(rgb, theme) {\n if (theme.mode === 0) {\n return modifyLightSchemeColor(rgb, theme);\n }\n const pole = getFgPole(theme);\n return modifyColorWithCache(rgb, {\n ...theme,\n mode: 0\n }, modifyFgHSL, pole);\n}\nfunction modifyBorderHSL({\n h,\n s,\n l,\n a\n}, poleFg, poleBg) {\n const isDark = l < 0.5;\n const isNeutral = l < 0.2 || s < 0.24;\n let hx = h;\n let sx = s;\n if (isNeutral) {\n if (isDark) {\n hx = poleFg.h;\n sx = poleFg.s;\n } else {\n hx = poleBg.h;\n sx = poleBg.s;\n }\n }\n const lx = (0,_utils_math__WEBPACK_IMPORTED_MODULE_1__.scale)(l, 0, 1, 0.5, 0.2);\n return {\n h: hx,\n s: sx,\n l: lx,\n a\n };\n}\nfunction modifyBorderColor(rgb, theme) {\n if (theme.mode === 0) {\n return modifyLightSchemeColor(rgb, theme);\n }\n const poleFg = getFgPole(theme);\n const poleBg = getBgPole(theme);\n return modifyColorWithCache(rgb, {\n ...theme,\n mode: 0\n }, modifyBorderHSL, poleFg, poleBg);\n}\nfunction modifyShadowColor(rgb, filter) {\n return modifyBackgroundColor(rgb, filter);\n}\nfunction modifyGradientColor(rgb, filter) {\n return modifyBackgroundColor(rgb, filter);\n}\n\n//# sourceURL=webpack://dark-mode/./src/generators/modify-colors.js?"); |
| 50 |
|
| 51 |
/***/ }), |
| 52 |
|
| 53 |
/***/ "./src/generators/svg-filter.js": |
| 54 |
/*!**************************************!*\ |
| 55 |
!*** ./src/generators/svg-filter.js ***! |
| 56 |
\**************************************/ |
| 57 |
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { |
| 58 |
|
| 59 |
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ createSVGFilterStylesheet: () => (/* binding */ createSVGFilterStylesheet),\n/* harmony export */ getSVGFilterMatrixValue: () => (/* binding */ getSVGFilterMatrixValue),\n/* harmony export */ getSVGReverseFilterMatrixValue: () => (/* binding */ getSVGReverseFilterMatrixValue)\n/* harmony export */ });\n/* harmony import */ var _utils_matrix__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./utils/matrix */ \"./src/generators/utils/matrix.js\");\n/* harmony import */ var _css_filter__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./css-filter */ \"./src/generators/css-filter.js\");\n/* harmony import */ var _utils_platform__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/platform */ \"./src/utils/platform.js\");\n\n\n\nfunction createSVGFilterStylesheet(config, url, isTopFrame, fixes, index) {\n let filterValue;\n let reverseFilterValue;\n if (_utils_platform__WEBPACK_IMPORTED_MODULE_2__.isFirefox) {\n filterValue = getEmbeddedSVGFilterValue(getSVGFilterMatrixValue(config));\n reverseFilterValue = getEmbeddedSVGFilterValue(getSVGReverseFilterMatrixValue());\n } else {\n // Chrome fails with \"Unsafe attempt to load URL ... Domains, protocols and ports must match.\n filterValue = \"url(#dark-reader-filter)\";\n reverseFilterValue = \"url(#dark-reader-reverse-filter)\";\n }\n return (0,_css_filter__WEBPACK_IMPORTED_MODULE_1__.cssFilterStyleSheetTemplate)(filterValue, reverseFilterValue, config, url, isTopFrame, fixes, index);\n}\nfunction getEmbeddedSVGFilterValue(matrixValue) {\n const id = \"adminify-filter\";\n const svg = ['<svg xmlns=\"http://www.w3.org/2000/svg\">', `<filter id=\"${id}\" style=\"color-interpolation-filters: sRGB;\">`, `<feColorMatrix type=\"matrix\" values=\"${matrixValue}\" />`, \"</filter>\", \"</svg>\"].join(\"\");\n return `url(data:image/svg+xml;base64,${btoa(svg)}#${id})`;\n}\nfunction toSVGMatrix(matrix) {\n return matrix.slice(0, 4).map(m => m.map(m => m.toFixed(3)).join(\" \")).join(\" \");\n}\nfunction getSVGFilterMatrixValue(config) {\n return toSVGMatrix((0,_utils_matrix__WEBPACK_IMPORTED_MODULE_0__.createFilterMatrix)(config));\n}\nfunction getSVGReverseFilterMatrixValue() {\n return toSVGMatrix(_utils_matrix__WEBPACK_IMPORTED_MODULE_0__.Matrix.invertNHue());\n}\n\n//# sourceURL=webpack://dark-mode/./src/generators/svg-filter.js?"); |
| 60 |
|
| 61 |
/***/ }), |
| 62 |
|
| 63 |
/***/ "./src/generators/text-style.js": |
| 64 |
/*!**************************************!*\ |
| 65 |
!*** ./src/generators/text-style.js ***! |
| 66 |
\**************************************/ |
| 67 |
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { |
| 68 |
|
| 69 |
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ createTextStyle: () => (/* binding */ createTextStyle)\n/* harmony export */ });\nfunction createTextStyle(config) {\n const lines = [];\n // Don't target pre elements as they are preformatted element's e.g. code blocks\n // Exclude font libraries to preserve icons\n lines.push('*:not(pre, pre *, code, .far, .fa, .glyphicon, [class*=\"vjs-\"], .fab, .fa-github, .fas, .material-icons, .icofont, .typcn, mu, [class*=\"mu-\"], .glyphicon, .icon) {');\n if (config.useFont && config.fontFamily) {\n // TODO: Validate...\n lines.push(` font-family: ${config.fontFamily} !important;`);\n }\n if (config.textStroke > 0) {\n lines.push(` -webkit-text-stroke: ${config.textStroke}px !important;`);\n lines.push(` text-stroke: ${config.textStroke}px !important;`);\n }\n lines.push(\"}\");\n return lines.join(\"\\n\");\n}\n\n//# sourceURL=webpack://dark-mode/./src/generators/text-style.js?"); |
| 70 |
|
| 71 |
/***/ }), |
| 72 |
|
| 73 |
/***/ "./src/generators/utils/matrix.js": |
| 74 |
/*!****************************************!*\ |
| 75 |
!*** ./src/generators/utils/matrix.js ***! |
| 76 |
\****************************************/ |
| 77 |
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { |
| 78 |
|
| 79 |
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ Matrix: () => (/* binding */ Matrix),\n/* harmony export */ applyColorMatrix: () => (/* binding */ applyColorMatrix),\n/* harmony export */ createFilterMatrix: () => (/* binding */ createFilterMatrix)\n/* harmony export */ });\n/* harmony import */ var _utils_math__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../utils/math */ \"./src/utils/math.js\");\n\nfunction createFilterMatrix(config) {\n let m = Matrix.identity();\n if (config.sepia !== 0) {\n m = (0,_utils_math__WEBPACK_IMPORTED_MODULE_0__.multiplyMatrices)(m, Matrix.sepia(config.sepia / 100));\n }\n if (config.grayscale !== 0) {\n m = (0,_utils_math__WEBPACK_IMPORTED_MODULE_0__.multiplyMatrices)(m, Matrix.grayscale(config.grayscale / 100));\n }\n if (config.contrast !== 100) {\n m = (0,_utils_math__WEBPACK_IMPORTED_MODULE_0__.multiplyMatrices)(m, Matrix.contrast(config.contrast / 100));\n }\n if (config.brightness !== 100) {\n m = (0,_utils_math__WEBPACK_IMPORTED_MODULE_0__.multiplyMatrices)(m, Matrix.brightness(config.brightness / 100));\n }\n if (config.mode === 1) {\n m = (0,_utils_math__WEBPACK_IMPORTED_MODULE_0__.multiplyMatrices)(m, Matrix.invertNHue());\n }\n return m;\n}\nfunction applyColorMatrix([r, g, b], matrix) {\n const rgb = [[r / 255], [g / 255], [b / 255], [1], [1]];\n const result = (0,_utils_math__WEBPACK_IMPORTED_MODULE_0__.multiplyMatrices)(matrix, rgb);\n return [0, 1, 2].map(i => (0,_utils_math__WEBPACK_IMPORTED_MODULE_0__.clamp)(Math.round(result[i][0] * 255), 0, 255));\n}\nconst Matrix = {\n identity() {\n return [[1, 0, 0, 0, 0], [0, 1, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 0, 1, 0], [0, 0, 0, 0, 1]];\n },\n invertNHue() {\n return [[0.333, -0.667, -0.667, 0, 1], [-0.667, 0.333, -0.667, 0, 1], [-0.667, -0.667, 0.333, 0, 1], [0, 0, 0, 1, 0], [0, 0, 0, 0, 1]];\n },\n brightness(v) {\n return [[v, 0, 0, 0, 0], [0, v, 0, 0, 0], [0, 0, v, 0, 0], [0, 0, 0, 1, 0], [0, 0, 0, 0, 1]];\n },\n contrast(v) {\n const t = (1 - v) / 2;\n return [[v, 0, 0, 0, t], [0, v, 0, 0, t], [0, 0, v, 0, t], [0, 0, 0, 1, 0], [0, 0, 0, 0, 1]];\n },\n sepia(v) {\n return [[0.393 + 0.607 * (1 - v), 0.769 - 0.769 * (1 - v), 0.189 - 0.189 * (1 - v), 0, 0], [0.349 - 0.349 * (1 - v), 0.686 + 0.314 * (1 - v), 0.168 - 0.168 * (1 - v), 0, 0], [0.272 - 0.272 * (1 - v), 0.534 - 0.534 * (1 - v), 0.131 + 0.869 * (1 - v), 0, 0], [0, 0, 0, 1, 0], [0, 0, 0, 0, 1]];\n },\n grayscale(v) {\n return [[0.2126 + 0.7874 * (1 - v), 0.7152 - 0.7152 * (1 - v), 0.0722 - 0.0722 * (1 - v), 0, 0], [0.2126 - 0.2126 * (1 - v), 0.7152 + 0.2848 * (1 - v), 0.0722 - 0.0722 * (1 - v), 0, 0], [0.2126 - 0.2126 * (1 - v), 0.7152 - 0.7152 * (1 - v), 0.0722 + 0.9278 * (1 - v), 0, 0], [0, 0, 0, 1, 0], [0, 0, 0, 0, 1]];\n }\n};\n\n//# sourceURL=webpack://dark-mode/./src/generators/utils/matrix.js?"); |
| 80 |
|
| 81 |
/***/ }), |
| 82 |
|
| 83 |
/***/ "./src/generators/utils/parse.js": |
| 84 |
/*!***************************************!*\ |
| 85 |
!*** ./src/generators/utils/parse.js ***! |
| 86 |
\***************************************/ |
| 87 |
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { |
| 88 |
|
| 89 |
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ getDomain: () => (/* binding */ getDomain),\n/* harmony export */ getSitesFixesFor: () => (/* binding */ getSitesFixesFor),\n/* harmony export */ parseSitesFixesConfig: () => (/* binding */ parseSitesFixesConfig)\n/* harmony export */ });\n/* harmony import */ var _utils_url__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../utils/url */ \"./src/utils/url.js\");\n/* harmony import */ var _utils_text__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../utils/text */ \"./src/utils/text.js\");\n\n\nconst INDEX_CACHE_CLEANUP_INTERVAL_IN_MS = 60000;\nfunction parseSitesFixesConfig(text, options) {\n const sites = [];\n const blocks = text.replace(/\\r/g, \"\").split(/^\\s*={2,}\\s*$/gm);\n blocks.forEach(block => {\n const lines = block.split(\"\\n\");\n const commandIndices = [];\n lines.forEach((ln, i) => {\n if (ln.match(/^[A-Z]+(\\s[A-Z]+){0,2}$/)) {\n commandIndices.push(i);\n }\n });\n if (commandIndices.length === 0) {\n return;\n }\n const siteFix = {\n url: (0,_utils_text__WEBPACK_IMPORTED_MODULE_1__.parseArray)(lines.slice(0, commandIndices[0]).join(\"\\n\"))\n };\n commandIndices.forEach((commandIndex, i) => {\n const command = lines[commandIndex].trim();\n const valueText = lines.slice(commandIndex + 1, i === commandIndices.length - 1 ? lines.length : commandIndices[i + 1]).join(\"\\n\");\n const prop = options.getCommandPropName(command);\n if (!prop) {\n return;\n }\n const value = options.parseCommandValue(command, valueText);\n siteFix[prop] = value;\n });\n sites.push(siteFix);\n });\n return sites;\n}\n// URL patterns are guaranteed to not have protocol and leading '/'\nfunction getDomain(url) {\n try {\n return new URL(url).hostname.toLowerCase();\n } catch (error) {\n return url.split(\"/\")[0].toLowerCase();\n }\n}\n/*\n * Encode all offsets into a string, where each record is 7 bytes long:\n * - 4 bytes for start offset\n * - 3 bytes for record length (end offset - start offset)\n * Both values are stored in base 36 (radix 36) notation.\n * Maximum supported numbers:\n * - start offset must be no more than parseInt('zzzz', 36) = 1679615\n * - length must be no more than parseInt('zzz', 36) = 46655\n *\n * We have to encode offsets into a string to be able to save them in\n * chrome.storage.local for use in non-persistent background contexts.\n */\n// function encodeOffsets(offsets) {\n// return offsets\n// .map(([offset, length]) => {\n// const stringOffset = offset.toString(36);\n// const stringLength = length.toString(36);\n// return (\n// \"0\".repeat(4 - stringOffset.length) +\n// stringOffset +\n// \"0\".repeat(3 - stringLength.length) +\n// stringLength\n// );\n// })\n// .join(\"\");\n// }\n\nfunction decodeOffset(offsets, index) {\n const base = (4 + 3) * index;\n const offset = parseInt(offsets.substring(base + 0, base + 4), 36);\n const length = parseInt(offsets.substring(base + 4, base + 4 + 3), 36);\n return [offset, offset + length];\n}\n\n// function addLabel(set, label, index) {\n// if (!set[label]) {\n// set[label] = [index];\n// } else if (!set[label].includes(index)) {\n// set[label].push(index);\n// }\n// }\n\n// function extractDomainLabelsFromFullyQualifiedDomainWildcard(fullyQualifiedDomainWildcard) {\n// const postfixStart = fullyQualifiedDomainWildcard.lastIndexOf(\"*\");\n// const postfix = fullyQualifiedDomainWildcard.substring(postfixStart + 2);\n// if (postfixStart < 0 || postfix.length === 0) {\n// return fullyQualifiedDomainWildcard.split(\".\");\n// }\n// const labels = [postfix];\n// const prefix = fullyQualifiedDomainWildcard.substring(0, postfixStart);\n// prefix\n// .split(\".\")\n// .filter(Boolean)\n// .forEach((l) => labels.concat(l));\n// return labels;\n// }\n\n// function indexConfigURLs(urls) {\n// const domains = {};\n// const domainLabels = {};\n// const nonstandard = [];\n// const domainLabelFrequencies = {};\n// const domainLabelMembers = [];\n// for (let index = 0; index < urls.length; index++) {\n// const block = urls[index];\n// const blockDomainLabels = new Set();\n// for (const url of block) {\n// const domain = getDomain(url);\n// if (isFullyQualifiedDomain(domain)) {\n// addLabel(domains, domain, index);\n// } else if (isFullyQualifiedDomainWildcard(domain)) {\n// const labels = extractDomainLabelsFromFullyQualifiedDomainWildcard(domain);\n// domainLabelMembers.push({ labels, index });\n// labels.forEach((l) => blockDomainLabels.add(l));\n// } else {\n// // Sitefix parser encountered non-standard URL\n// nonstandard.push(index);\n// break;\n// }\n// }\n// // Compute domain label frequencies, counting each label within each fix only once\n// for (const label of blockDomainLabels) {\n// if (domainLabelFrequencies[label]) {\n// domainLabelFrequencies[label]++;\n// } else {\n// domainLabelFrequencies[label] = 1;\n// }\n// }\n// }\n// // For each domain name, find the most specific label\n// for (const { labels, index } of domainLabelMembers) {\n// let label = labels[0];\n// for (const currLabel of labels) {\n// if (domainLabelFrequencies[currLabel] < domainLabelFrequencies[label]) {\n// label = currLabel;\n// }\n// }\n// addLabel(domainLabels, label, index);\n// }\n// return { domains, domainLabels, nonstandard };\n// }\n\n// function processSiteFixesConfigBlock(text, offsets, recordStart, recordEnd, urls) {\n// // TODO: more formal definition of URLs and delimiters\n// const block = text.substring(recordStart, recordEnd);\n// const lines = block.split(\"\\n\");\n// const commandIndices = [];\n// lines.forEach((ln, i) => {\n// if (ln.match(/^[A-Z]+(\\s[A-Z]+){0,2}$/)) {\n// commandIndices.push(i);\n// }\n// });\n// if (commandIndices.length === 0) {\n// return;\n// }\n// offsets.push([recordStart, recordEnd - recordStart]);\n// const urls_ = parseArray(lines.slice(0, commandIndices[0]).join(\"\\n\"));\n// urls.push(urls_);\n// }\n\n// function extractURLsFromSiteFixesConfig(text) {\n// const urls = [];\n// // Array of tuples, where first number is an offset of record start and second number is record length.\n// const offsets = [];\n// let recordStart = 0;\n// // Delimiter between two blocks\n// const delimiterRegex = /^\\s*={2,}\\s*$/gm;\n// let delimiter;\n// while ((delimiter = delimiterRegex.exec(text))) {\n// const nextDelimiterStart = delimiter.index;\n// const nextDelimiterEnd = delimiter.index + delimiter[0].length;\n// processSiteFixesConfigBlock(text, offsets, recordStart, nextDelimiterStart, urls);\n// recordStart = nextDelimiterEnd;\n// }\n// processSiteFixesConfigBlock(text, offsets, recordStart, text.length, urls);\n// return { urls, offsets };\n// }\n\n// export function indexSitesFixesConfig(text) {\n// const { urls, offsets } = extractURLsFromSiteFixesConfig(text);\n// const { domains, domainLabels, nonstandard } = indexConfigURLs(urls);\n// return {\n// offsets: encodeOffsets(offsets),\n// domains,\n// domainLabels,\n// nonstandard,\n// cacheDomainIndex: {},\n// cacheSiteFix: {},\n// cacheCleanupTimer: null,\n// };\n// }\n\nfunction lookupConfigURLsInDomainLabels(domain, recordIds, currRecordIds, getAllRecordURLs) {\n for (const recordId of currRecordIds) {\n const recordURLs = getAllRecordURLs(recordId);\n for (const ruleUrl of recordURLs) {\n const wildcard = getDomain(ruleUrl);\n if ((0,_utils_url__WEBPACK_IMPORTED_MODULE_0__.isFullyQualifiedDomainWildcard)(wildcard) && (0,_utils_url__WEBPACK_IMPORTED_MODULE_0__.fullyQualifiedDomainMatchesWildcard)(wildcard, domain)) {\n recordIds.push(recordId);\n } else {\n // Skip this rule, since the label match must have come from a different URL\n }\n }\n }\n}\nfunction lookupConfigURLs(domain, index, getAllRecordURLs) {\n const labels = domain.split(\".\");\n let recordIds = [];\n // Common fix\n if (\"*\" in index.domainLabels) {\n recordIds = recordIds.concat(index.domainLabels[\"*\"]);\n }\n // Wildcard fixes\n for (const label of labels) {\n // We need to use in operator because ids are 0-based and 0 is falsy\n if (label in index.domainLabels) {\n const currRecordIds = index.domainLabels[label];\n lookupConfigURLsInDomainLabels(domain, recordIds, currRecordIds, getAllRecordURLs);\n }\n }\n for (let i = 0; i < labels.length; i++) {\n const substring = labels.slice(i).join(\".\");\n if (substring in index.domains) {\n recordIds = recordIds.concat(index.domains[substring]);\n }\n if (substring in index.domainLabels) {\n const currRecordIds = index.domainLabels[substring];\n lookupConfigURLsInDomainLabels(domain, recordIds, currRecordIds, getAllRecordURLs);\n }\n }\n // Backwards compatibility: check for nonssend over nonstandard patterns, which will be filtered out\n // via regex in content script\n if (index.nonstandard) {\n for (const currRecordId of index.nonstandard) {\n const urls = getAllRecordURLs(currRecordId);\n if (urls.some(url => (0,_utils_url__WEBPACK_IMPORTED_MODULE_0__.isURLMatched)(domain, getDomain(url)))) {\n recordIds.push(currRecordId);\n continue;\n }\n }\n }\n // Deduplicate array elements\n recordIds = Array.from(new Set(recordIds));\n return recordIds;\n}\n/**\n * Extracts a single site fix and parses it (cached)\n * @param text the fix file\n * @param index site fix index\n * @param options fix parsing options\n * @param id numeric index of the fix\n * @returns a single fix\n */\nfunction getSiteFix(text, index, options, id) {\n if (id in index.cacheSiteFix) {\n return index.cacheSiteFix[id];\n }\n const [blockStart, blockEnd] = decodeOffset(index.offsets, id);\n const block = text.substring(blockStart, blockEnd);\n const fix = parseSitesFixesConfig(block, options)[0];\n index.cacheSiteFix[id] = fix;\n return fix;\n}\n/**\n * This function uses setTimeout instead of Alarms API so that background context can\n * go incative (resulting in cleanup of all context variables) and then not be awoken\n * by the alarm.\n * @param index\n */\nfunction scheduleCacheCleanup(index) {\n // if (__TEST__) {\n // return;\n // }\n clearTimeout(index.cacheCleanupTimer);\n index.cacheCleanupTimer = setTimeout(() => {\n index.cacheCleanupTimer = null;\n index.cacheDomainIndex = {};\n index.cacheSiteFix = {};\n }, INDEX_CACHE_CLEANUP_INTERVAL_IN_MS);\n}\n/**\n * Given a URL, raw fixes, and an index, finds the applicable fixes.\n * Note that dependents assume that the first returned fix is a generic fix (has URL pattern '*').\n *\n * This method uses two levels of caching:\n * - caching the site fixes keyed by a numeric id (to avoid re-parsing the site fixes)\n * - caching the numeric ids keyed by domain (to avoid re-computing lists of site fixes for the same site,\n * which is useful if user has multiple tabs of the same site and toggles Dark Reader on)\n */\nfunction getSitesFixesFor(url, text, index, options) {\n const records = [];\n const domain = getDomain(url);\n if (!index.cacheDomainIndex[domain]) {\n index.cacheDomainIndex[domain] = lookupConfigURLs(domain, index, recordId => getSiteFix(text, index, options, recordId).url);\n }\n const recordIds = index.cacheDomainIndex[domain];\n for (const recordId of recordIds) {\n const fix = getSiteFix(text, index, options, recordId);\n records.push(fix);\n }\n scheduleCacheCleanup(index);\n return records;\n}\n\n// export function indexSiteListConfig(text) {\n// const urls = parseArray(text);\n// const urls2D = urls.map((u) => [u]);\n// const { domains, domainLabels, nonstandard } = indexConfigURLs(urls2D);\n// return { domains, domainLabels, nonstandard, urls };\n// }\n\n// function getSiteListFor(url, index) {\n// const domain = getDomain(url);\n// const recordIds = lookupConfigURLs(domain, index, (recordId) => [index.urls[recordId]]);\n// const result = [];\n// for (const recordId of recordIds) {\n// result.push(index.urls[recordId]);\n// }\n// return result;\n// }\n\n// export function isURLInSiteList(url, index) {\n// if (index === null) {\n// return false;\n// }\n// const urls = getSiteListFor(url, index);\n// return isURLInList(url, urls);\n// }\n\n//# sourceURL=webpack://dark-mode/./src/generators/utils/parse.js?"); |
| 90 |
|
| 91 |
/***/ }), |
| 92 |
|
| 93 |
/***/ "./src/inject/dynamic-theme/css-rules.js": |
| 94 |
/*!***********************************************!*\ |
| 95 |
!*** ./src/inject/dynamic-theme/css-rules.js ***! |
| 96 |
\***********************************************/ |
| 97 |
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { |
| 98 |
|
| 99 |
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ cssImportRegex: () => (/* binding */ cssImportRegex),\n/* harmony export */ cssURLRegex: () => (/* binding */ cssURLRegex),\n/* harmony export */ getCSSBaseBath: () => (/* binding */ getCSSBaseBath),\n/* harmony export */ getCSSURLValue: () => (/* binding */ getCSSURLValue),\n/* harmony export */ iterateCSSDeclarations: () => (/* binding */ iterateCSSDeclarations),\n/* harmony export */ iterateCSSRules: () => (/* binding */ iterateCSSRules),\n/* harmony export */ removeCSSComments: () => (/* binding */ removeCSSComments),\n/* harmony export */ replaceCSSFontFace: () => (/* binding */ replaceCSSFontFace),\n/* harmony export */ replaceCSSRelativeURLsWithAbsolute: () => (/* binding */ replaceCSSRelativeURLsWithAbsolute)\n/* harmony export */ });\n/* harmony import */ var _utils_array__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../utils/array */ \"./src/utils/array.js\");\n/* harmony import */ var _utils_platform__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../utils/platform */ \"./src/utils/platform.js\");\n/* harmony import */ var _utils_url__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../utils/url */ \"./src/utils/url.js\");\n\n\n\n// import { logInfo, logWarn } from \"../utils/log\";\n\nfunction iterateCSSRules(rules, iterate, onMediaRuleError) {\n (0,_utils_array__WEBPACK_IMPORTED_MODULE_0__.forEach)(rules, rule => {\n // Don't rely on prototype or instanceof, they are slow implementations within the browsers.\n // However we can rely on certain properties to indentify which CSSRule we are dealing with.\n // And it's 2x so fast, https://jsben.ch/B0eLa\n if (rule.selectorText) {\n iterate(rule);\n } else if (rule.href) {\n try {\n iterateCSSRules(rule.styleSheet.cssRules, iterate, onMediaRuleError);\n } catch (err) {\n // logInfo(`Found a non-loaded link.`);\n onMediaRuleError && onMediaRuleError();\n }\n } else if (rule.media) {\n const media = Array.from(rule.media);\n const isScreenOrAllOrQuery = media.some(m => m.startsWith(\"screen\") || m.startsWith(\"all\") || m.startsWith(\"(\"));\n const isPrintOrSpeech = media.some(m => m.startsWith(\"print\") || m.startsWith(\"speech\"));\n if (isScreenOrAllOrQuery || !isPrintOrSpeech) {\n iterateCSSRules(rule.cssRules, iterate, onMediaRuleError);\n }\n } else if (rule.conditionText) {\n if (CSS.supports(rule.conditionText)) {\n iterateCSSRules(rule.cssRules, iterate, onMediaRuleError);\n }\n } else {\n // logWarn(`CSSRule type not supported`, rule);\n }\n });\n}\n\n// These properties are not iterable\n// when they depend on variables\nconst shorthandVarDependantProperties = [\"background\", \"border\", \"border-color\", \"border-bottom\", \"border-left\", \"border-right\", \"border-top\", \"outline\", \"outline-color\"];\nconst shorthandVarDepPropRegexps = _utils_platform__WEBPACK_IMPORTED_MODULE_1__.isSafari ? shorthandVarDependantProperties.map(prop => {\n const regexp = new RegExp(`${prop}:\\\\s*(.*?)\\\\s*;`);\n return [prop, regexp];\n}) : null;\nfunction iterateCSSDeclarations(style, iterate) {\n (0,_utils_array__WEBPACK_IMPORTED_MODULE_0__.forEach)(style, property => {\n const value = style.getPropertyValue(property).trim();\n if (!value) {\n return;\n }\n iterate(property, value);\n });\n\n // Bigger sites like gmail.com and google.com will love this optimization.\n // As a side-effect, styles with a lot of `var(` will notice a maximum slowdown of ~50ms.\n // Against the bigger sites that saves around ~150ms+ it's a good win.\n const cssText = style.cssText;\n if (cssText.includes(\"var(\")) {\n if (_utils_platform__WEBPACK_IMPORTED_MODULE_1__.isSafari) {\n // Safari doesn't show shorthand properties' values\n shorthandVarDepPropRegexps.forEach(([prop, regexp]) => {\n const match = cssText.match(regexp);\n if (match && match[1]) {\n const val = match[1].trim();\n iterate(prop, val);\n }\n });\n } else {\n shorthandVarDependantProperties.forEach(prop => {\n const val = style.getPropertyValue(prop);\n if (val && val.includes(\"var(\")) {\n iterate(prop, val);\n }\n });\n }\n }\n}\nconst cssURLRegex = /url\\((('.*?')|(\".*?\")|([^\\)]*?))\\)/g;\nconst cssImportRegex = /@import\\s*(url\\()?(('.+?')|(\".+?\")|([^\\)]*?))\\)? ?(screen)?;?/gi;\n\n// First try to extract the CSS URL value. Then do some post fixes, like unescaping\n// backslashes in the URL. (Chromium don't handle this natively). Remove all newlines\n// beforehand, otherwise `.` will fail matching the content within the url, as it\n// doesn't match any linebreaks.\nfunction getCSSURLValue(cssURL) {\n return cssURL.trim().replace(/[\\n\\r\\\\]+/g, \"\").replace(/^url\\((.*)\\)$/, \"$1\").trim().replace(/^\"(.*)\"$/, \"$1\").replace(/^'(.*)'$/, \"$1\").replace(/(?:\\\\(.))/g, \"$1\");\n}\nfunction getCSSBaseBath(url) {\n const cssURL = (0,_utils_url__WEBPACK_IMPORTED_MODULE_2__.parseURL)(url);\n return `${cssURL.origin}${cssURL.pathname.replace(/\\?.*$/, \"\").replace(/(\\/)([^\\/]+)$/i, \"$1\")}`;\n}\nfunction replaceCSSRelativeURLsWithAbsolute($css, cssBasePath) {\n return $css.replace(cssURLRegex, match => {\n const pathValue = getCSSURLValue(match);\n // Sites can have any kind of specified URL, thus also invalid ones.\n // To prevent the whole operation from failing, let's just skip those\n // invalid URL's and let them be invalid.\n try {\n return `url('${(0,_utils_url__WEBPACK_IMPORTED_MODULE_2__.getAbsoluteURL)(cssBasePath, pathValue)}')`;\n } catch (err) {\n // logWarn(\"Not able to replace relative URL with Absolute URL, skipping\");\n return match;\n }\n });\n}\nconst cssCommentsRegex = /\\/\\*[\\s\\S]*?\\*\\//g;\nfunction removeCSSComments($css) {\n return $css.replace(cssCommentsRegex, \"\");\n}\nconst fontFaceRegex = /@font-face\\s*{[^}]*}/g;\nfunction replaceCSSFontFace($css) {\n return $css.replace(fontFaceRegex, \"\");\n}\n\n//# sourceURL=webpack://dark-mode/./src/inject/dynamic-theme/css-rules.js?"); |
| 100 |
|
| 101 |
/***/ }), |
| 102 |
|
| 103 |
/***/ "./src/inject/dynamic-theme/image.js": |
| 104 |
/*!*******************************************!*\ |
| 105 |
!*** ./src/inject/dynamic-theme/image.js ***! |
| 106 |
\*******************************************/ |
| 107 |
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { |
| 108 |
|
| 109 |
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ cleanImageProcessingCache: () => (/* binding */ cleanImageProcessingCache),\n/* harmony export */ getFilteredImageDataURL: () => (/* binding */ getFilteredImageDataURL),\n/* harmony export */ getImageDetails: () => (/* binding */ getImageDetails)\n/* harmony export */ });\n/* harmony import */ var _generators_svg_filter__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../generators/svg-filter */ \"./src/generators/svg-filter.js\");\n/* harmony import */ var _utils_color__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../utils/color */ \"./src/utils/color.js\");\n/* harmony import */ var _utils_network__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../utils/network */ \"./src/utils/network.js\");\n/* harmony import */ var _utils_async_queue__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../utils/async-queue */ \"./src/utils/async-queue.js\");\n\n// import { bgFetch } from \"./network\";\n\n\n// import { logInfo, logWarn } from \"../utils/log\";\n\nconst imageManager = new _utils_async_queue__WEBPACK_IMPORTED_MODULE_3__[\"default\"]();\nasync function getImageDetails(url) {\n return new Promise(async (resolve, reject) => {\n let dataURL;\n if (url.startsWith(\"data:\")) {\n dataURL = url;\n } else {\n try {\n dataURL = await getImageDataURL(url);\n } catch (error) {\n reject(error);\n return;\n }\n }\n try {\n const image = await urlToImage(dataURL);\n imageManager.addToQueue(() => {\n resolve({\n src: url,\n dataURL,\n width: image.naturalWidth,\n height: image.naturalHeight,\n ...analyzeImage(image)\n });\n });\n } catch (error) {\n reject(error);\n }\n });\n}\nasync function getImageDataURL(url) {\n const parsedURL = new URL(url);\n if (parsedURL.origin === location.origin) {\n return await (0,_utils_network__WEBPACK_IMPORTED_MODULE_2__.loadAsDataURL)(url);\n }\n // return await bgFetch({ url, responseType: \"data-url\" });\n}\nasync function urlToImage(url) {\n return new Promise((resolve, reject) => {\n const image = new Image();\n image.onload = () => resolve(image);\n image.onerror = () => reject(`Unable to load image ${url}`);\n image.src = url;\n });\n}\nconst MAX_ANALIZE_PIXELS_COUNT = 32 * 32;\nlet canvas;\nlet context;\nfunction createCanvas() {\n const maxWidth = MAX_ANALIZE_PIXELS_COUNT;\n const maxHeight = MAX_ANALIZE_PIXELS_COUNT;\n canvas = document.createElement(\"canvas\");\n canvas.width = maxWidth;\n canvas.height = maxHeight;\n context = canvas.getContext(\"2d\", {\n willReadFrequently: true\n });\n context.imageSmoothingEnabled = false;\n}\nfunction removeCanvas() {\n canvas = null;\n context = null;\n}\n\n// 5MB\nconst MAX_IMAGE_SIZE = 5 * 1024 * 1024;\nfunction analyzeImage(image) {\n if (!canvas) {\n createCanvas();\n }\n const {\n naturalWidth,\n naturalHeight\n } = image;\n if (naturalHeight === 0 || naturalWidth === 0) {\n // logWarn(`logWarn(Image is empty ${image.currentSrc})`);\n return {\n isDark: false,\n isLight: false,\n isTransparent: false,\n isLarge: false,\n isTooLarge: false\n };\n }\n\n // Get good appromized image size in memory terms.\n // Width * Height * 4(R, G, B, A) and 500B(metadata) because rgba can contain up to 3 digits.\n const size = naturalWidth * naturalHeight * 4;\n // Is it over ~5MB? Let's not decode the image, it's something that's useless to analyze.\n // And very performance senstive for the browser to decode this image(~50ms) and take into account\n // It's being async `drawImage` calls.\n if (size > MAX_IMAGE_SIZE) {\n // logInfo(\"Skipped large image analyzing(Larger than 5mb in memory)\");\n return {\n isDark: false,\n isLight: false,\n isTransparent: false,\n isLarge: false,\n isTooLarge: true\n };\n }\n const naturalPixelsCount = naturalWidth * naturalHeight;\n const k = Math.min(1, Math.sqrt(MAX_ANALIZE_PIXELS_COUNT / naturalPixelsCount));\n const width = Math.ceil(naturalWidth * k);\n const height = Math.ceil(naturalHeight * k);\n context.clearRect(0, 0, width, height);\n context.drawImage(image, 0, 0, naturalWidth, naturalHeight, 0, 0, width, height);\n const imageData = context.getImageData(0, 0, width, height);\n const d = imageData.data;\n const TRANSPARENT_ALPHA_THRESHOLD = 0.05;\n const DARK_LIGHTNESS_THRESHOLD = 0.4;\n const LIGHT_LIGHTNESS_THRESHOLD = 0.7;\n let transparentPixelsCount = 0;\n let darkPixelsCount = 0;\n let lightPixelsCount = 0;\n let i, x, y;\n let r, g, b, a;\n let l;\n for (y = 0; y < height; y++) {\n for (x = 0; x < width; x++) {\n i = 4 * (y * width + x);\n r = d[i + 0];\n g = d[i + 1];\n b = d[i + 2];\n a = d[i + 3];\n if (a / 255 < TRANSPARENT_ALPHA_THRESHOLD) {\n transparentPixelsCount++;\n } else {\n l = (0,_utils_color__WEBPACK_IMPORTED_MODULE_1__.getSRGBLightness)(r, g, b);\n if (l < DARK_LIGHTNESS_THRESHOLD) {\n darkPixelsCount++;\n }\n if (l > LIGHT_LIGHTNESS_THRESHOLD) {\n lightPixelsCount++;\n }\n }\n }\n }\n const totalPixelsCount = width * height;\n const opaquePixelsCount = totalPixelsCount - transparentPixelsCount;\n const DARK_IMAGE_THRESHOLD = 0.7;\n const LIGHT_IMAGE_THRESHOLD = 0.7;\n const TRANSPARENT_IMAGE_THRESHOLD = 0.1;\n const LARGE_IMAGE_PIXELS_COUNT = 800 * 600;\n return {\n isDark: darkPixelsCount / opaquePixelsCount >= DARK_IMAGE_THRESHOLD,\n isLight: lightPixelsCount / opaquePixelsCount >= LIGHT_IMAGE_THRESHOLD,\n isTransparent: transparentPixelsCount / totalPixelsCount >= TRANSPARENT_IMAGE_THRESHOLD,\n isLarge: naturalPixelsCount >= LARGE_IMAGE_PIXELS_COUNT,\n isTooLarge: false\n };\n}\nfunction getFilteredImageDataURL({\n dataURL,\n width,\n height\n}, theme) {\n const matrix = (0,_generators_svg_filter__WEBPACK_IMPORTED_MODULE_0__.getSVGFilterMatrixValue)(theme);\n const svg = [`<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"${width}\" height=\"${height}\">`, \"<defs>\", '<filter id=\"adminify-image-filter\">', `<feColorMatrix type=\"matrix\" values=\"${matrix}\" />`, \"</filter>\", \"</defs>\", `<image width=\"${width}\" height=\"${height}\" filter=\"url(#adminify-image-filter)\" xlink:href=\"${dataURL}\" />`, \"</svg>\"].join(\"\");\n return `data:image/svg+xml;base64,${btoa(svg)}`;\n}\nfunction cleanImageProcessingCache() {\n imageManager && imageManager.stopQueue();\n removeCanvas();\n}\n\n//# sourceURL=webpack://dark-mode/./src/inject/dynamic-theme/image.js?"); |
| 110 |
|
| 111 |
/***/ }), |
| 112 |
|
| 113 |
/***/ "./src/inject/dynamic-theme/index.js": |
| 114 |
/*!*******************************************!*\ |
| 115 |
!*** ./src/inject/dynamic-theme/index.js ***! |
| 116 |
\*******************************************/ |
| 117 |
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { |
| 118 |
|
| 119 |
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ cleanDynamicThemeCache: () => (/* binding */ cleanDynamicThemeCache),\n/* harmony export */ removeDynamicTheme: () => (/* binding */ removeDynamicTheme),\n/* harmony export */ run_createThemeAndWatchForUpdates: () => (/* binding */ run_createThemeAndWatchForUpdates)\n/* harmony export */ });\n/* harmony import */ var _default__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../default */ \"./src/default.js\");\n/* harmony import */ var _generators_css_filter__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../generators/css-filter */ \"./src/generators/css-filter.js\");\n/* harmony import */ var _generators_modify_colors__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../generators/modify-colors */ \"./src/generators/modify-colors.js\");\n/* harmony import */ var _utils_array__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../utils/array */ \"./src/utils/array.js\");\n/* harmony import */ var _utils_color__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../utils/color */ \"./src/utils/color.js\");\n/* harmony import */ var _utils_throttle__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../utils/throttle */ \"./src/utils/throttle.js\");\n/* harmony import */ var _utils_url__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../utils/url */ \"./src/utils/url.js\");\n/* harmony import */ var _utils_visibility__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../utils/visibility */ \"./src/utils/visibility.js\");\n/* harmony import */ var _utils_dom__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../utils/dom */ \"./src/inject/utils/dom.js\");\n/* harmony import */ var _inline_style__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./inline-style */ \"./src/inject/dynamic-theme/inline-style.js\");\n/* harmony import */ var _modify_css__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./modify-css */ \"./src/inject/dynamic-theme/modify-css.js\");\n/* harmony import */ var _style_manager__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./style-manager */ \"./src/inject/dynamic-theme/style-manager.js\");\n/* harmony import */ var _variables__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./variables */ \"./src/inject/dynamic-theme/variables.js\");\n/* harmony import */ var _watch__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./watch */ \"./src/inject/dynamic-theme/watch.js\");\n\n\n\n\n\n\n\n\n\n// import { logInfo } from \"../utils/log\";\n\n\n\n\n\nlet filter = _default__WEBPACK_IMPORTED_MODULE_0__.DEFAULT_THEME;\nlet fixes = null;\nlet isIFrame = null;\nconst styleManagers = new Map();\nlet ignoredImageAnalysisSelectors = [];\nlet ignoredInlineSelectors = [];\nconst adoptedStyleManagers = [];\nfunction createOrUpdateStyle(className, root = document.head || document) {\n let element = root.querySelector(`.${className}`);\n if (!element) {\n element = document.createElement(\"style\");\n element.classList.add(\"adminify\");\n element.classList.add(className);\n element.media = \"screen\";\n element.textContent = \"\";\n }\n return element;\n}\nconst nodePositionWatchers = new Map();\n\n// **important**\nfunction setupNodePositionWatcher(node, alias) {\n nodePositionWatchers.has(alias) && nodePositionWatchers.get(alias).stop();\n nodePositionWatchers.set(alias, (0,_utils_dom__WEBPACK_IMPORTED_MODULE_8__.watchForNodePosition)(node, \"head\"));\n}\nfunction createStaticStyleOverrides() {\n const fallbackStyle = createOrUpdateStyle(\"adminify--fallback\", document);\n fallbackStyle.textContent = (0,_modify_css__WEBPACK_IMPORTED_MODULE_10__.getModifiedFallbackStyle)(filter, {\n strict: true\n });\n document.head.insertBefore(fallbackStyle, document.head.firstChild);\n setupNodePositionWatcher(fallbackStyle, \"fallback\");\n const userAgentStyle = createOrUpdateStyle(\"adminify--user-agent\");\n userAgentStyle.textContent = (0,_modify_css__WEBPACK_IMPORTED_MODULE_10__.getModifiedUserAgentStyle)(filter, isIFrame, filter.styleSystemControls);\n document.head.insertBefore(userAgentStyle, fallbackStyle.nextSibling);\n setupNodePositionWatcher(userAgentStyle, \"user-agent\");\n const textStyle = createOrUpdateStyle(\"adminify--text\");\n if (filter.useFont || filter.textStroke > 0) {\n textStyle.textContent = createTextStyle(filter);\n } else {\n textStyle.textContent = \"\";\n }\n document.head.insertBefore(textStyle, fallbackStyle.nextSibling);\n setupNodePositionWatcher(textStyle, \"text\");\n const invertStyle = createOrUpdateStyle(\"adminify--invert\");\n if (fixes && Array.isArray(fixes.invert) && fixes.invert.length > 0) {\n invertStyle.textContent = [`${fixes.invert.join(\", \")} {`, ` filter: ${(0,_generators_css_filter__WEBPACK_IMPORTED_MODULE_1__.getCSSFilterValue)({\n ...filter,\n contrast: filter.mode === 0 ? filter.contrast : clamp(filter.contrast - 10, 0, 100)\n })} !important;`, \"}\"].join(\"\\n\");\n } else {\n invertStyle.textContent = \"\";\n }\n document.head.insertBefore(invertStyle, textStyle.nextSibling);\n setupNodePositionWatcher(invertStyle, \"invert\");\n const inlineStyle = createOrUpdateStyle(\"adminify--inline\");\n inlineStyle.textContent = (0,_inline_style__WEBPACK_IMPORTED_MODULE_9__.getInlineOverrideStyle)();\n document.head.insertBefore(inlineStyle, invertStyle.nextSibling);\n setupNodePositionWatcher(inlineStyle, \"inline\");\n const overrideStyle = createOrUpdateStyle(\"adminify--override\");\n overrideStyle.textContent = fixes && fixes.css ? replaceCSSTemplates(fixes.css) : \"\";\n document.head.appendChild(overrideStyle);\n setupNodePositionWatcher(overrideStyle, \"override\");\n const variableStyle = createOrUpdateStyle(\"adminify--variables\");\n const selectionColors = (0,_modify_css__WEBPACK_IMPORTED_MODULE_10__.getSelectionColor)(filter);\n const {\n darkSchemeBackgroundColor,\n darkSchemeTextColor,\n lightSchemeBackgroundColor,\n lightSchemeTextColor,\n mode\n } = filter;\n let schemeBackgroundColor = mode === 0 ? lightSchemeBackgroundColor : darkSchemeBackgroundColor;\n let schemeTextColor = mode === 0 ? lightSchemeTextColor : darkSchemeTextColor;\n schemeBackgroundColor = (0,_generators_modify_colors__WEBPACK_IMPORTED_MODULE_2__.modifyBackgroundColor)((0,_utils_color__WEBPACK_IMPORTED_MODULE_4__.parseColorWithCache)(schemeBackgroundColor), filter);\n schemeTextColor = (0,_generators_modify_colors__WEBPACK_IMPORTED_MODULE_2__.modifyForegroundColor)((0,_utils_color__WEBPACK_IMPORTED_MODULE_4__.parseColorWithCache)(schemeTextColor), filter);\n variableStyle.textContent = [`:root {`, ` --adminify-neutral-background: ${schemeBackgroundColor};`, ` --adminify-neutral-text: ${schemeTextColor};`, ` --adminify-selection-background: ${selectionColors.backgroundColorSelection};`, ` --adminify-selection-text: ${selectionColors.foregroundColorSelection};`, `}`].join(\"\\n\");\n document.head.insertBefore(variableStyle, inlineStyle.nextSibling);\n setupNodePositionWatcher(variableStyle, \"variables\");\n const rootVarsStyle = createOrUpdateStyle(\"adminify--root-vars\");\n document.head.insertBefore(rootVarsStyle, variableStyle.nextSibling);\n\n //Media Grayscale\n if (filter.imgGrayscale || filter.videoGrayscale) {\n const adminifyMediaCSS = createOrUpdateStyle(\"adminify--media\", document);\n adminifyMediaCSS.textContent = `${filter.imgGrayscale ? `img{filter: grayscale(${filter.imgGrayscalePercent})}` : \"\"}${filter.videoGrayscale ? `video, .wp-block-embed-youtube, .wp-block-embed[data-title=\"YouTube\"]{filter: grayscale(${filter.videoGrayscalePercent})}` : \"\"}`;\n document.head.insertBefore(adminifyMediaCSS, rootVarsStyle.nextSibling);\n setupNodePositionWatcher(adminifyMediaCSS, \"media\");\n }\n}\nfunction runDynamicStyle() {\n createDynamicStyleOverrides();\n // watchForUpdates();\n}\nfunction createThemeAndWatchForUpdates() {\n createStaticStyleOverrides();\n if (!(0,_utils_visibility__WEBPACK_IMPORTED_MODULE_7__.documentIsVisible)() && !filter.immediateModify) {\n (0,_utils_visibility__WEBPACK_IMPORTED_MODULE_7__.setDocumentVisibilityListener)(runDynamicStyle);\n } else {\n runDynamicStyle();\n }\n // changeMetaThemeColorWhenAvailable(filter);\n}\n\n//Main Func\nfunction run_createThemeAndWatchForUpdates(config) {\n filter = {\n ...filter,\n ...config\n };\n createThemeAndWatchForUpdates();\n}\nlet loadingStylesCounter = 0;\nconst loadingStyles = new Set();\nfunction createManager(element) {\n const loadingStyleId = ++loadingStylesCounter;\n // logInfo(`New manager for element, with loadingStyleID ${loadingStyleId}`, element);\n\n function loadingStart() {\n if (!(0,_utils_dom__WEBPACK_IMPORTED_MODULE_8__.isDOMReady)() || !(0,_utils_visibility__WEBPACK_IMPORTED_MODULE_7__.documentIsVisible)()) {\n loadingStyles.add(loadingStyleId);\n // logInfo(`Current amount of styles loading: ${loadingStyles.size}`);\n\n const fallbackStyle = document.querySelector(\".adminify--fallback\");\n if (!fallbackStyle.textContent) {\n fallbackStyle.textContent = (0,_modify_css__WEBPACK_IMPORTED_MODULE_10__.getModifiedFallbackStyle)(filter, {\n strict: false\n });\n }\n }\n }\n function loadingEnd() {\n loadingStyles.delete(loadingStyleId);\n // logInfo(`Removed loadingStyle ${loadingStyleId}, now awaiting: ${loadingStyles.size}`);\n // logInfo(`To-do to be loaded`, loadingStyles);\n\n // if (loadingStyles.size === 0 && isDOMReady()) {\n if (loadingStyles.size === 0) {\n cleanFallbackStyle();\n }\n }\n function update() {\n const details = manager.details({\n secondRound: true\n });\n if (!details) {\n return;\n }\n _variables__WEBPACK_IMPORTED_MODULE_12__.variablesStore.addRulesForMatching(details.rules);\n _variables__WEBPACK_IMPORTED_MODULE_12__.variablesStore.matchVariablesAndDependants();\n manager.render(filter, ignoredImageAnalysisSelectors);\n }\n const manager = (0,_style_manager__WEBPACK_IMPORTED_MODULE_11__.manageStyle)(element, {\n update,\n loadingStart,\n loadingEnd\n });\n styleManagers.set(element, manager);\n return manager;\n}\nfunction createDynamicStyleOverrides() {\n const allStyles = (0,_style_manager__WEBPACK_IMPORTED_MODULE_11__.getManageableStyles)(document);\n const newManagers = allStyles.filter(style => !styleManagers.has(style)).map(style => createManager(style));\n newManagers.map(manager => manager.details({\n secondRound: false\n })).filter(detail => detail && detail.rules.length > 0).forEach(detail => {\n _variables__WEBPACK_IMPORTED_MODULE_12__.variablesStore.addRulesForMatching(detail.rules);\n });\n _variables__WEBPACK_IMPORTED_MODULE_12__.variablesStore.matchVariablesAndDependants();\n _variables__WEBPACK_IMPORTED_MODULE_12__.variablesStore.setOnRootVariableChange(() => {\n const rootVarsStyle = createOrUpdateStyle(\"adminify--root-vars\");\n _variables__WEBPACK_IMPORTED_MODULE_12__.variablesStore.putRootVars(rootVarsStyle, filter);\n });\n const rootVarsStyle = createOrUpdateStyle(\"adminify--root-vars\");\n _variables__WEBPACK_IMPORTED_MODULE_12__.variablesStore.putRootVars(rootVarsStyle, filter);\n styleManagers.forEach(manager => manager.render(filter, ignoredImageAnalysisSelectors));\n if (loadingStyles.size === 0) {\n cleanFallbackStyle();\n }\n newManagers.forEach(manager => manager.watch());\n const inlineStyleElements = (0,_utils_array__WEBPACK_IMPORTED_MODULE_3__.toArray)(document.querySelectorAll(_inline_style__WEBPACK_IMPORTED_MODULE_9__.INLINE_STYLE_SELECTOR));\n (0,_utils_dom__WEBPACK_IMPORTED_MODULE_8__.iterateShadowHosts)(document.documentElement, host => {\n createShadowStaticStyleOverrides(host.shadowRoot);\n const elements = host.shadowRoot.querySelectorAll(_inline_style__WEBPACK_IMPORTED_MODULE_9__.INLINE_STYLE_SELECTOR);\n if (elements.length > 0) {\n push(inlineStyleElements, elements);\n }\n });\n inlineStyleElements.forEach(el => (0,_inline_style__WEBPACK_IMPORTED_MODULE_9__.overrideInlineStyle)(el, filter, ignoredInlineSelectors, ignoredImageAnalysisSelectors));\n // handleAdoptedStyleSheets(document);\n}\nfunction cleanFallbackStyle() {\n const fallback = document.querySelector(\".adminify--fallback\");\n if (fallback) {\n fallback.textContent = \"\";\n }\n}\nfunction replaceCSSTemplates($cssText) {\n return $cssText.replace(/\\${(.+?)}/g, (_, $color) => {\n const color = (0,_utils_color__WEBPACK_IMPORTED_MODULE_4__.parseColorWithCache)($color);\n if (color) {\n return (0,_generators_modify_colors__WEBPACK_IMPORTED_MODULE_2__.modifyColor)(color, filter);\n }\n // logWarn(\"Couldn't parse CSSTemplate's color.\");\n return $color;\n });\n}\nfunction createShadowStaticStyleOverrides(root) {\n // The shadow DOM may not be populated yet and the custom element implementation\n // may assume that unpopulated shadow root is empty and inadvertently remove\n // Dark Reader's overrides\n const uninit = root.firstChild === null;\n createShadowStaticStyleOverridesInner(root);\n if (uninit) {\n delayedCreateShadowStaticStyleOverrides(root);\n }\n}\nconst shadowRootsWithOverrides = new Set();\nfunction createShadowStaticStyleOverridesInner(root) {\n const inlineStyle = createOrUpdateStyle(\"adminify--inline\", root);\n inlineStyle.textContent = (0,_inline_style__WEBPACK_IMPORTED_MODULE_9__.getInlineOverrideStyle)();\n root.insertBefore(inlineStyle, root.firstChild);\n const overrideStyle = createOrUpdateStyle(\"adminify--override\", root);\n overrideStyle.textContent = fixes && fixes.css ? replaceCSSTemplates(fixes.css) : \"\";\n root.insertBefore(overrideStyle, inlineStyle.nextSibling);\n const invertStyle = createOrUpdateStyle(\"adminify--invert\", root);\n if (fixes && Array.isArray(fixes.invert) && fixes.invert.length > 0) {\n invertStyle.textContent = [`${fixes.invert.join(\", \")} {`, ` filter: ${(0,_generators_css_filter__WEBPACK_IMPORTED_MODULE_1__.getCSSFilterValue)({\n ...filter,\n contrast: filter.mode === 0 ? filter.contrast : clamp(filter.contrast - 10, 0, 100)\n })} !important;`, \"}\"].join(\"\\n\");\n } else {\n invertStyle.textContent = \"\";\n }\n root.insertBefore(invertStyle, overrideStyle.nextSibling);\n shadowRootsWithOverrides.add(root);\n}\nfunction delayedCreateShadowStaticStyleOverrides(root) {\n const observer = new MutationObserver((mutations, observer) => {\n // Disconnect observer immediatelly before making any other changes\n observer.disconnect();\n\n // Do not make any changes unless Dark Reader's fixes have been removed\n for (const {\n type,\n removedNodes\n } of mutations) {\n if (type === \"childList\") {\n for (const {\n nodeName,\n className\n } of removedNodes) {\n if (nodeName === \"STYLE\" && [\"adminify adminify--inline\", \"adminify adminify--override\", \"adminify adminify--invert\"].includes(className)) {\n createShadowStaticStyleOverridesInner(root);\n return;\n }\n }\n }\n }\n });\n observer.observe(root, {\n childList: true\n });\n}\n\n//remove styles\n\nfunction removeManager(element) {\n const manager = styleManagers.get(element);\n if (manager) {\n manager.destroy();\n styleManagers.delete(element);\n }\n}\nconst throttledRenderAllStyles = (0,_utils_throttle__WEBPACK_IMPORTED_MODULE_5__.throttle)(callback => {\n styleManagers.forEach(manager => manager.render(filter, ignoredImageAnalysisSelectors));\n adoptedStyleManagers.forEach(manager => manager.render(filter, ignoredImageAnalysisSelectors));\n callback && callback();\n});\nconst cancelRendering = function () {\n throttledRenderAllStyles.cancel();\n};\nlet metaObserver;\nfunction removeDynamicTheme() {\n document.documentElement.removeAttribute(`data-adminify-mode`);\n document.documentElement.removeAttribute(`data-adminify-scheme`);\n cleanDynamicThemeCache();\n (0,_utils_dom__WEBPACK_IMPORTED_MODULE_8__.removeNode)(document.querySelector(\".adminify--fallback\"));\n if (document.head) {\n // restoreMetaThemeColor();\n (0,_utils_dom__WEBPACK_IMPORTED_MODULE_8__.removeNode)(document.head.querySelector(\".adminify--user-agent\"));\n (0,_utils_dom__WEBPACK_IMPORTED_MODULE_8__.removeNode)(document.head.querySelector(\".adminify--text\"));\n (0,_utils_dom__WEBPACK_IMPORTED_MODULE_8__.removeNode)(document.head.querySelector(\".adminify--invert\"));\n (0,_utils_dom__WEBPACK_IMPORTED_MODULE_8__.removeNode)(document.head.querySelector(\".adminify--inline\"));\n (0,_utils_dom__WEBPACK_IMPORTED_MODULE_8__.removeNode)(document.head.querySelector(\".adminify--override\"));\n (0,_utils_dom__WEBPACK_IMPORTED_MODULE_8__.removeNode)(document.head.querySelector(\".adminify--variables\"));\n (0,_utils_dom__WEBPACK_IMPORTED_MODULE_8__.removeNode)(document.head.querySelector(\".adminify--root-vars\"));\n (0,_utils_dom__WEBPACK_IMPORTED_MODULE_8__.removeNode)(document.head.querySelector('meta[name=\"adminify\"]'));\n // removeProxy();\n }\n shadowRootsWithOverrides.forEach(root => {\n (0,_utils_dom__WEBPACK_IMPORTED_MODULE_8__.removeNode)(root.querySelector(\".adminify--inline\"));\n (0,_utils_dom__WEBPACK_IMPORTED_MODULE_8__.removeNode)(root.querySelector(\".adminify--override\"));\n });\n shadowRootsWithOverrides.clear();\n (0,_utils_array__WEBPACK_IMPORTED_MODULE_3__.forEach)(styleManagers.keys(), el => removeManager(el));\n loadingStyles.clear();\n\n // cleanLoadingLinks();\n // forEach(document.querySelectorAll(\".adminify\"), removeNode);\n // adoptedStyleManagers.forEach((manager) => {\n // manager.destroy();\n // });\n // adoptedStyleManagers.splice(0);\n // metaObserver && metaObserver.disconnect();\n}\nfunction cleanDynamicThemeCache() {\n _variables__WEBPACK_IMPORTED_MODULE_12__.variablesStore.clear();\n _utils_url__WEBPACK_IMPORTED_MODULE_6__.parsedURLCache.clear();\n (0,_utils_visibility__WEBPACK_IMPORTED_MODULE_7__.removeDocumentVisibilityListener)();\n cancelRendering();\n stopWatchingForUpdates();\n (0,_modify_css__WEBPACK_IMPORTED_MODULE_10__.cleanModificationCache)();\n (0,_utils_color__WEBPACK_IMPORTED_MODULE_4__.clearColorCache)();\n}\nfunction stopWatchingForUpdates() {\n styleManagers.forEach(manager => manager.pause());\n stopStylePositionWatchers();\n (0,_watch__WEBPACK_IMPORTED_MODULE_13__.stopWatchingForStyleChanges)();\n (0,_inline_style__WEBPACK_IMPORTED_MODULE_9__.stopWatchingForInlineStyles)();\n (0,_utils_dom__WEBPACK_IMPORTED_MODULE_8__.removeDOMReadyListener)(onDOMReady);\n (0,_utils_dom__WEBPACK_IMPORTED_MODULE_8__.cleanReadyStateCompleteListeners)();\n}\nfunction stopStylePositionWatchers() {\n (0,_utils_array__WEBPACK_IMPORTED_MODULE_3__.forEach)(nodePositionWatchers.values(), watcher => watcher.stop());\n nodePositionWatchers.clear();\n}\nfunction onDOMReady() {\n if (loadingStyles.size === 0) {\n cleanFallbackStyle();\n return;\n }\n // logWarn(`DOM is ready, but still have styles being loaded.`, loadingStyles);\n}\n\n//# sourceURL=webpack://dark-mode/./src/inject/dynamic-theme/index.js?"); |
| 120 |
|
| 121 |
/***/ }), |
| 122 |
|
| 123 |
/***/ "./src/inject/dynamic-theme/inline-style.js": |
| 124 |
/*!**************************************************!*\ |
| 125 |
!*** ./src/inject/dynamic-theme/inline-style.js ***! |
| 126 |
\**************************************************/ |
| 127 |
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { |
| 128 |
|
| 129 |
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ INLINE_STYLE_SELECTOR: () => (/* binding */ INLINE_STYLE_SELECTOR),\n/* harmony export */ getInlineOverrideStyle: () => (/* binding */ getInlineOverrideStyle),\n/* harmony export */ overrideInlineStyle: () => (/* binding */ overrideInlineStyle),\n/* harmony export */ stopWatchingForInlineStyles: () => (/* binding */ stopWatchingForInlineStyles)\n/* harmony export */ });\n/* harmony import */ var _utils_array__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../utils/array */ \"./src/utils/array.js\");\n/* harmony import */ var _utils_dom__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../utils/dom */ \"./src/inject/utils/dom.js\");\n/* harmony import */ var _css_rules__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./css-rules */ \"./src/inject/dynamic-theme/css-rules.js\");\n/* harmony import */ var _modify_css__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./modify-css */ \"./src/inject/dynamic-theme/modify-css.js\");\n/* harmony import */ var _variables__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./variables */ \"./src/inject/dynamic-theme/variables.js\");\n\n\n\n\n\nconst overrides = {\n \"background-color\": {\n customProp: \"--adminify-inline-bgcolor\",\n cssProp: \"background-color\",\n dataAttr: \"data-adminify-inline-bgcolor\"\n },\n \"background-image\": {\n customProp: \"--adminify-inline-bgimage\",\n cssProp: \"background-image\",\n dataAttr: \"data-adminify-inline-bgimage\"\n },\n \"border-color\": {\n customProp: \"--adminify-inline-border\",\n cssProp: \"border-color\",\n dataAttr: \"data-adminify-inline-border\"\n },\n \"border-bottom-color\": {\n customProp: \"--adminify-inline-border-bottom\",\n cssProp: \"border-bottom-color\",\n dataAttr: \"data-adminify-inline-border-bottom\"\n },\n \"border-left-color\": {\n customProp: \"--adminify-inline-border-left\",\n cssProp: \"border-left-color\",\n dataAttr: \"data-adminify-inline-border-left\"\n },\n \"border-right-color\": {\n customProp: \"--adminify-inline-border-right\",\n cssProp: \"border-right-color\",\n dataAttr: \"data-adminify-inline-border-right\"\n },\n \"border-top-color\": {\n customProp: \"--adminify-inline-border-top\",\n cssProp: \"border-top-color\",\n dataAttr: \"data-adminify-inline-border-top\"\n },\n \"box-shadow\": {\n customProp: \"--adminify-inline-boxshadow\",\n cssProp: \"box-shadow\",\n dataAttr: \"data-adminify-inline-boxshadow\"\n },\n color: {\n customProp: \"--adminify-inline-color\",\n cssProp: \"color\",\n dataAttr: \"data-adminify-inline-color\"\n },\n fill: {\n customProp: \"--adminify-inline-fill\",\n cssProp: \"fill\",\n dataAttr: \"data-adminify-inline-fill\"\n },\n stroke: {\n customProp: \"--adminify-inline-stroke\",\n cssProp: \"stroke\",\n dataAttr: \"data-adminify-inline-stroke\"\n },\n \"outline-color\": {\n customProp: \"--adminify-inline-outline\",\n cssProp: \"outline-color\",\n dataAttr: \"data-adminify-inline-outline\"\n },\n \"stop-color\": {\n customProp: \"--adminify-inline-stopcolor\",\n cssProp: \"stop-color\",\n dataAttr: \"data-adminify-inline-stopcolor\"\n }\n};\nconst overridesList = Object.values(overrides);\nconst normalizedPropList = {};\noverridesList.forEach(({\n cssProp,\n customProp\n}) => normalizedPropList[customProp] = cssProp);\nconst INLINE_STYLE_ATTRS = [\"style\", \"fill\", \"stop-color\", \"stroke\", \"bgcolor\", \"color\"];\nconst INLINE_STYLE_SELECTOR = INLINE_STYLE_ATTRS.map(attr => `[${attr}]`).join(\", \");\nfunction getInlineOverrideStyle() {\n return overridesList.map(({\n dataAttr,\n customProp,\n cssProp\n }) => {\n return [`[${dataAttr}] {`, ` ${cssProp}: var(${customProp}) !important;`, \"}\"].join(\"\\n\");\n }).join(\"\\n\");\n}\nconst inlineStyleCache = new WeakMap();\nconst filterProps = [\"brightness\", \"contrast\", \"grayscale\", \"sepia\", \"mode\"];\nfunction getInlineStyleCacheKey(el, theme) {\n return INLINE_STYLE_ATTRS.map(attr => `${attr}=\"${el.getAttribute(attr)}\"`).concat(filterProps.map(prop => `${prop}=\"${theme[prop]}\"`)).join(\" \");\n}\nfunction overrideInlineStyle(element, theme, ignoreInlineSelectors, ignoreImageSelectors) {\n const cacheKey = getInlineStyleCacheKey(element, theme);\n if (cacheKey === inlineStyleCache.get(element)) {\n return;\n }\n const unsetProps = new Set(Object.keys(overrides));\n function setCustomProp(targetCSSProp, modifierCSSProp, cssVal) {\n const isPropertyVariable = targetCSSProp.startsWith(\"--\");\n const {\n customProp,\n dataAttr\n } = isPropertyVariable ? {} : overrides[targetCSSProp];\n const mod = (0,_modify_css__WEBPACK_IMPORTED_MODULE_3__.getModifiableCSSDeclaration)(modifierCSSProp, cssVal, {\n style: element.style\n }, _variables__WEBPACK_IMPORTED_MODULE_4__.variablesStore, ignoreImageSelectors, null);\n if (!mod) {\n return;\n }\n let value = mod.value;\n if (typeof value === \"function\") {\n value = value(theme);\n }\n\n // typeof value === 'object' always evaluate to true when\n // `isPropertyVariable` is true, but it serves as a type hint for typescript.\n // Such that `as ReturnType<CSSVariableModifier>` won't error about the possible\n // string type.\n if (isPropertyVariable && typeof value === \"object\") {\n const typedValue = value;\n typedValue.declarations.forEach(({\n property,\n value\n }) => {\n !(value instanceof Promise) && element.style.setProperty(property, value);\n });\n\n // TODO: add listener for `onTypeChange`.\n } else {\n element.style.setProperty(customProp, value);\n if (!element.hasAttribute(dataAttr)) {\n element.setAttribute(dataAttr, \"\");\n }\n unsetProps.delete(targetCSSProp);\n }\n }\n if (ignoreInlineSelectors.length > 0) {\n if (shouldIgnoreInlineStyle(element, ignoreInlineSelectors)) {\n unsetProps.forEach(cssProp => {\n element.removeAttribute(overrides[cssProp].dataAttr);\n });\n return;\n }\n }\n if (element.hasAttribute(\"bgcolor\")) {\n let value = element.getAttribute(\"bgcolor\");\n if (value.match(/^[0-9a-f]{3}$/i) || value.match(/^[0-9a-f]{6}$/i)) {\n value = `#${value}`;\n }\n setCustomProp(\"background-color\", \"background-color\", value);\n }\n\n // We can catch some link elements here, that are from `<link rel=\"mask-icon\" color=\"#000000\">`.\n // It's valid HTML code according to the specs, https://html.spec.whatwg.org/#attr-link-color\n // We don't want to touch such links, as it cause weird browser behavior (silent DOMException).\n if (element.hasAttribute(\"color\") && element.rel !== \"mask-icon\") {\n let value = element.getAttribute(\"color\");\n if (value.match(/^[0-9a-f]{3}$/i) || value.match(/^[0-9a-f]{6}$/i)) {\n value = `#${value}`;\n }\n setCustomProp(\"color\", \"color\", value);\n }\n if (element instanceof SVGElement) {\n if (element.hasAttribute(\"fill\")) {\n const SMALL_SVG_LIMIT = 32;\n const value = element.getAttribute(\"fill\");\n if (value !== \"none\") {\n if (!(element instanceof SVGTextElement)) {\n // getBoundingClientRect forces a layout change. And when it happens and\n // the DOM is not in the `complete` readystate, it will cause the layout to be drawn\n // and it will cause a layout of unstyled content which results in white flashes.\n // Therefore, check if the DOM is at the `complete` readystate.\n const handleSVGElement = () => {\n const {\n width,\n height\n } = element.getBoundingClientRect();\n const isBg = width > SMALL_SVG_LIMIT || height > SMALL_SVG_LIMIT;\n setCustomProp(\"fill\", isBg ? \"background-color\" : \"color\", value);\n };\n if ((0,_utils_dom__WEBPACK_IMPORTED_MODULE_1__.isReadyStateComplete)()) {\n handleSVGElement();\n } else {\n (0,_utils_dom__WEBPACK_IMPORTED_MODULE_1__.addReadyStateCompleteListener)(handleSVGElement);\n }\n } else {\n setCustomProp(\"fill\", \"color\", value);\n }\n }\n }\n if (element.hasAttribute(\"stop-color\")) {\n setCustomProp(\"stop-color\", \"background-color\", element.getAttribute(\"stop-color\"));\n }\n }\n if (element.hasAttribute(\"stroke\")) {\n const value = element.getAttribute(\"stroke\");\n setCustomProp(\"stroke\", element instanceof SVGLineElement || element instanceof SVGTextElement ? \"border-color\" : \"color\", value);\n }\n element.style && (0,_css_rules__WEBPACK_IMPORTED_MODULE_2__.iterateCSSDeclarations)(element.style, (property, value) => {\n // Temporarily ignore background images due to the possible performance\n // issues and complexity of handling async requests.\n if (property === \"background-image\" && value.includes(\"url\")) {\n return;\n }\n if (overrides.hasOwnProperty(property) || property.startsWith(\"--\") && !normalizedPropList[property]) {\n setCustomProp(property, property, value);\n } else {\n const overridenProp = normalizedPropList[property];\n if (overridenProp && !element.style.getPropertyValue(overridenProp) && !element.hasAttribute(overridenProp)) {\n if (overridenProp === \"background-color\" && element.hasAttribute(\"bgcolor\")) {\n return;\n }\n element.style.setProperty(property, \"\");\n }\n }\n });\n if (element.style && element instanceof SVGTextElement && element.style.fill) {\n setCustomProp(\"fill\", \"color\", element.style.getPropertyValue(\"fill\"));\n }\n (0,_utils_array__WEBPACK_IMPORTED_MODULE_0__.forEach)(unsetProps, cssProp => {\n element.removeAttribute(overrides[cssProp].dataAttr);\n });\n inlineStyleCache.set(element, getInlineStyleCacheKey(element, theme));\n}\nconst treeObservers = new Map();\nconst attrObservers = new Map();\nfunction stopWatchingForInlineStyles() {\n treeObservers.forEach(o => o.disconnect());\n attrObservers.forEach(o => o.disconnect());\n treeObservers.clear();\n attrObservers.clear();\n}\n\n//# sourceURL=webpack://dark-mode/./src/inject/dynamic-theme/inline-style.js?"); |
| 130 |
|
| 131 |
/***/ }), |
| 132 |
|
| 133 |
/***/ "./src/inject/dynamic-theme/modify-css.js": |
| 134 |
/*!************************************************!*\ |
| 135 |
!*** ./src/inject/dynamic-theme/modify-css.js ***! |
| 136 |
\************************************************/ |
| 137 |
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { |
| 138 |
|
| 139 |
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ cleanModificationCache: () => (/* binding */ cleanModificationCache),\n/* harmony export */ getBgImageModifier: () => (/* binding */ getBgImageModifier),\n/* harmony export */ getModifiableCSSDeclaration: () => (/* binding */ getModifiableCSSDeclaration),\n/* harmony export */ getModifiedFallbackStyle: () => (/* binding */ getModifiedFallbackStyle),\n/* harmony export */ getModifiedUserAgentStyle: () => (/* binding */ getModifiedUserAgentStyle),\n/* harmony export */ getSelectionColor: () => (/* binding */ getSelectionColor),\n/* harmony export */ getShadowModifier: () => (/* binding */ getShadowModifier),\n/* harmony export */ getShadowModifierWithInfo: () => (/* binding */ getShadowModifierWithInfo)\n/* harmony export */ });\n/* harmony import */ var _generators_modify_colors__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../generators/modify-colors */ \"./src/generators/modify-colors.js\");\n/* harmony import */ var _utils_color__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../utils/color */ \"./src/utils/color.js\");\n/* harmony import */ var _utils_math__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../utils/math */ \"./src/utils/math.js\");\n/* harmony import */ var _utils_parsing__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../utils/parsing */ \"./src/utils/parsing.js\");\n/* harmony import */ var _utils_platform__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../utils/platform */ \"./src/utils/platform.js\");\n/* harmony import */ var _utils_text__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../utils/text */ \"./src/utils/text.js\");\n/* harmony import */ var _utils_url__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../utils/url */ \"./src/utils/url.js\");\n/* harmony import */ var _css_rules__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./css-rules */ \"./src/inject/dynamic-theme/css-rules.js\");\n/* harmony import */ var _image__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./image */ \"./src/inject/dynamic-theme/image.js\");\n\n\n\n\n\n\n\n// import { logInfo, logWarn } from \"../utils/log\";\n\n\nlet fallbackFactory = null;\nfunction getPriority(ruleStyle, property) {\n return Boolean(ruleStyle && ruleStyle.getPropertyPriority(property));\n}\nconst unparsableColors = new Set([\"inherit\", \"transparent\", \"initial\", \"currentcolor\", \"none\", \"unset\"]);\nfunction getColorModifier(prop, value, rule) {\n if (unparsableColors.has(value.toLowerCase())) {\n return value;\n }\n const rgb = (0,_utils_color__WEBPACK_IMPORTED_MODULE_1__.parseColorWithCache)(value);\n if (!rgb) {\n // logWarn(\"Couldn't parse color\", value);\n return null;\n }\n if (prop.includes(\"background\")) {\n if (rule.style.webkitMaskImage && rule.style.webkitMaskImage !== \"none\" || rule.style.webkitMask && !rule.style.webkitMask.startsWith(\"none\") || rule.style.mask && rule.style.mask !== \"none\" || rule.style.getPropertyValue(\"mask-image\") && rule.style.getPropertyValue(\"mask-image\") !== \"none\") {\n return filter => (0,_generators_modify_colors__WEBPACK_IMPORTED_MODULE_0__.modifyForegroundColor)(rgb, filter);\n }\n return filter => (0,_generators_modify_colors__WEBPACK_IMPORTED_MODULE_0__.modifyBackgroundColor)(rgb, filter);\n }\n if (prop.includes(\"border\") || prop.includes(\"outline\")) {\n return filter => (0,_generators_modify_colors__WEBPACK_IMPORTED_MODULE_0__.modifyBorderColor)(rgb, filter);\n }\n return filter => (0,_generators_modify_colors__WEBPACK_IMPORTED_MODULE_0__.modifyForegroundColor)(rgb, filter);\n}\nfunction getVariableModifier(variablesStore, prop, value, rule, ignoredImgSelectors, isCancelled) {\n return variablesStore.getModifierForVariable({\n varName: prop,\n sourceValue: value,\n rule,\n ignoredImgSelectors,\n isCancelled\n });\n}\nfunction getVariableDependantModifier(variablesStore, prop, value) {\n return variablesStore.getModifierForVarDependant(prop, value);\n}\nfunction getShadowModifier(value) {\n const shadowModifier = getShadowModifierWithInfo(value);\n if (!shadowModifier) {\n return null;\n }\n return theme => shadowModifier(theme).result;\n}\nfunction getModifiableCSSDeclaration(property, value, rule, variablesStore, ignoreImageSelectors, isCancelled) {\n if (property.startsWith(\"--\")) {\n const modifier = getVariableModifier(variablesStore, property, value, rule, ignoreImageSelectors, isCancelled);\n if (modifier) {\n return {\n property,\n value: modifier,\n important: getPriority(rule.style, property),\n sourceValue: value\n };\n }\n } else if (value.includes(\"var(\")) {\n const modifier = getVariableDependantModifier(variablesStore, property, value);\n if (modifier) {\n return {\n property,\n value: modifier,\n important: getPriority(rule.style, property),\n sourceValue: value\n };\n }\n } else if (property === \"color-scheme\") {\n // Note: this if statement needs to be above the next one\n // logWarn(\"CSS property color-scheme is not supported\");\n return null;\n } else if (property.includes(\"color\") && property !== \"-webkit-print-color-adjust\" || property === \"fill\" || property === \"stroke\" || property === \"stop-color\") {\n const modifier = getColorModifier(property, value, rule);\n if (modifier) {\n return {\n property,\n value: modifier,\n important: getPriority(rule.style, property),\n sourceValue: value\n };\n }\n } else if (property === \"background-image\" || property === \"list-style-image\") {\n const modifier = getBgImageModifier(value, rule, ignoreImageSelectors, isCancelled);\n if (modifier) {\n return {\n property,\n value: modifier,\n important: getPriority(rule.style, property),\n sourceValue: value\n };\n }\n } else if (property.includes(\"shadow\")) {\n const modifier = getShadowModifier(value);\n if (modifier) {\n return {\n property,\n value: modifier,\n important: getPriority(rule.style, property),\n sourceValue: value\n };\n }\n }\n return null;\n}\n\n// **important**\nfunction getModifiedFallbackStyle(filter, {\n strict\n}) {\n const factory = fallbackFactory || defaultFallbackFactory;\n return factory(filter, {\n strict\n });\n}\nfunction joinSelectors(...selectors) {\n return selectors.filter(Boolean).join(\", \");\n}\n\n// **important**\nfunction defaultFallbackFactory(filter, {\n strict\n}) {\n const lines = [];\n // https://github.com/darkreader/darkreader/issues/3618#issuecomment-895477598\n const isMicrosoft = [\"microsoft.com\", \"docs.microsoft.com\"].includes(location.hostname);\n lines.push(`html, body, ${strict ? `body :not(iframe)${isMicrosoft ? ':not(div[style^=\"position:absolute;top:0;left:-\"]' : \"\"}` : \"body > :not(iframe)\"} {`);\n lines.push(` background-color: ${(0,_generators_modify_colors__WEBPACK_IMPORTED_MODULE_0__.modifyBackgroundColor)({\n r: 255,\n g: 255,\n b: 255\n }, filter)} !important;`);\n lines.push(` border-color: ${(0,_generators_modify_colors__WEBPACK_IMPORTED_MODULE_0__.modifyBorderColor)({\n r: 64,\n g: 64,\n b: 64\n }, filter)} !important;`);\n lines.push(` color: ${(0,_generators_modify_colors__WEBPACK_IMPORTED_MODULE_0__.modifyForegroundColor)({\n r: 0,\n g: 0,\n b: 0\n }, filter)} !important;`);\n lines.push(\"}\");\n return lines.join(\"\\n\");\n}\nfunction getSelectionColor(theme) {\n let backgroundColorSelection;\n let foregroundColorSelection;\n if (theme.selectionColor === \"auto\") {\n backgroundColorSelection = (0,_generators_modify_colors__WEBPACK_IMPORTED_MODULE_0__.modifyBackgroundColor)({\n r: 0,\n g: 96,\n b: 212\n }, {\n ...theme,\n grayscale: 0\n });\n foregroundColorSelection = (0,_generators_modify_colors__WEBPACK_IMPORTED_MODULE_0__.modifyForegroundColor)({\n r: 255,\n g: 255,\n b: 255\n }, {\n ...theme,\n grayscale: 0\n });\n } else {\n const rgb = (0,_utils_color__WEBPACK_IMPORTED_MODULE_1__.parseColorWithCache)(theme.selectionColor);\n const hsl = rgbToHSL(rgb);\n backgroundColorSelection = theme.selectionColor;\n if (hsl.l < 0.5) {\n foregroundColorSelection = \"#FFF\";\n } else {\n foregroundColorSelection = \"#000\";\n }\n }\n return {\n backgroundColorSelection,\n foregroundColorSelection\n };\n}\nfunction getModifiedSelectionStyle(theme) {\n const lines = [];\n const modifiedSelectionColor = getSelectionColor(theme);\n const backgroundColorSelection = modifiedSelectionColor.backgroundColorSelection;\n const foregroundColorSelection = modifiedSelectionColor.foregroundColorSelection;\n [\"::selection\", \"::-moz-selection\"].forEach(selection => {\n lines.push(`${selection} {`);\n lines.push(` background-color: ${backgroundColorSelection} !important;`);\n lines.push(` color: ${foregroundColorSelection} !important;`);\n lines.push(\"}\");\n });\n return lines.join(\"\\n\");\n}\nfunction getModifiedUserAgentStyle(theme, isIFrame, styleSystemControls) {\n const lines = [];\n if (!isIFrame) {\n lines.push(\"html {\");\n lines.push(` background-color: ${(0,_generators_modify_colors__WEBPACK_IMPORTED_MODULE_0__.modifyBackgroundColor)({\n r: 255,\n g: 255,\n b: 255\n }, theme)} !important;`);\n lines.push(\"}\");\n }\n if (_utils_platform__WEBPACK_IMPORTED_MODULE_4__.isCSSColorSchemePropSupported) {\n lines.push(\"html {\");\n lines.push(` color-scheme: ${theme.mode === 1 ? \"dark\" : \"dark light\"} !important;`);\n lines.push(\"}\");\n }\n const bgSelectors = joinSelectors(isIFrame ? \"\" : \"html, body\", styleSystemControls ? \"input, textarea, select, button, dialog\" : \"\");\n if (bgSelectors) {\n lines.push(`${bgSelectors} {`);\n lines.push(` background-color: ${(0,_generators_modify_colors__WEBPACK_IMPORTED_MODULE_0__.modifyBackgroundColor)({\n r: 255,\n g: 255,\n b: 255\n }, theme)};`);\n lines.push(\"}\");\n }\n lines.push(`${joinSelectors(\"html, body\", styleSystemControls ? \"input, textarea, select, button\" : \"\")} {`);\n lines.push(` border-color: ${(0,_generators_modify_colors__WEBPACK_IMPORTED_MODULE_0__.modifyBorderColor)({\n r: 76,\n g: 76,\n b: 76\n }, theme)};`);\n lines.push(` color: ${(0,_generators_modify_colors__WEBPACK_IMPORTED_MODULE_0__.modifyForegroundColor)({\n r: 0,\n g: 0,\n b: 0\n }, theme)};`);\n lines.push(\"}\");\n lines.push(\"a {\");\n lines.push(` color: ${(0,_generators_modify_colors__WEBPACK_IMPORTED_MODULE_0__.modifyForegroundColor)({\n r: 0,\n g: 64,\n b: 255\n }, theme)};`);\n lines.push(\"}\");\n lines.push(\"table {\");\n lines.push(` border-color: ${(0,_generators_modify_colors__WEBPACK_IMPORTED_MODULE_0__.modifyBorderColor)({\n r: 128,\n g: 128,\n b: 128\n }, theme)};`);\n lines.push(\"}\");\n lines.push(\"::placeholder {\");\n lines.push(` color: ${(0,_generators_modify_colors__WEBPACK_IMPORTED_MODULE_0__.modifyForegroundColor)({\n r: 169,\n g: 169,\n b: 169\n }, theme)};`);\n lines.push(\"}\");\n lines.push(\"input:-webkit-autofill,\");\n lines.push(\"textarea:-webkit-autofill,\");\n lines.push(\"select:-webkit-autofill {\");\n lines.push(` background-color: ${(0,_generators_modify_colors__WEBPACK_IMPORTED_MODULE_0__.modifyBackgroundColor)({\n r: 250,\n g: 255,\n b: 189\n }, theme)} !important;`);\n lines.push(` color: ${(0,_generators_modify_colors__WEBPACK_IMPORTED_MODULE_0__.modifyForegroundColor)({\n r: 0,\n g: 0,\n b: 0\n }, theme)} !important;`);\n lines.push(\"}\");\n if (theme.scrollbarColor) {\n lines.push(getModifiedScrollbarStyle(theme));\n }\n if (theme.selectionColor) {\n lines.push(getModifiedSelectionStyle(theme));\n }\n return lines.join(\"\\n\");\n}\nfunction getModifiedScrollbarStyle(theme) {\n const lines = [];\n let colorTrack;\n let colorIcons;\n let colorThumb;\n let colorThumbHover;\n let colorThumbActive;\n let colorCorner;\n if (theme.scrollbarColor === \"auto\") {\n colorTrack = (0,_generators_modify_colors__WEBPACK_IMPORTED_MODULE_0__.modifyBackgroundColor)({\n r: 241,\n g: 241,\n b: 241\n }, theme);\n colorIcons = (0,_generators_modify_colors__WEBPACK_IMPORTED_MODULE_0__.modifyForegroundColor)({\n r: 96,\n g: 96,\n b: 96\n }, theme);\n colorThumb = (0,_generators_modify_colors__WEBPACK_IMPORTED_MODULE_0__.modifyBackgroundColor)({\n r: 176,\n g: 176,\n b: 176\n }, theme);\n colorThumbHover = (0,_generators_modify_colors__WEBPACK_IMPORTED_MODULE_0__.modifyBackgroundColor)({\n r: 144,\n g: 144,\n b: 144\n }, theme);\n colorThumbActive = (0,_generators_modify_colors__WEBPACK_IMPORTED_MODULE_0__.modifyBackgroundColor)({\n r: 96,\n g: 96,\n b: 96\n }, theme);\n colorCorner = (0,_generators_modify_colors__WEBPACK_IMPORTED_MODULE_0__.modifyBackgroundColor)({\n r: 255,\n g: 255,\n b: 255\n }, theme);\n } else {\n const rgb = (0,_utils_color__WEBPACK_IMPORTED_MODULE_1__.parseColorWithCache)(theme.scrollbarColor);\n const hsl = rgbToHSL(rgb);\n const isLight = hsl.l > 0.5;\n const lighten = lighter => ({\n ...hsl,\n l: (0,_utils_math__WEBPACK_IMPORTED_MODULE_2__.clamp)(hsl.l + lighter, 0, 1)\n });\n const darken = darker => ({\n ...hsl,\n l: (0,_utils_math__WEBPACK_IMPORTED_MODULE_2__.clamp)(hsl.l - darker, 0, 1)\n });\n colorTrack = hslToString(darken(0.4));\n colorIcons = hslToString(isLight ? darken(0.4) : lighten(0.4));\n colorThumb = hslToString(hsl);\n colorThumbHover = hslToString(lighten(0.1));\n colorThumbActive = hslToString(lighten(0.2));\n colorCorner = hslToString(darken(0.5));\n }\n lines.push(\"::-webkit-scrollbar {\");\n lines.push(` background-color: ${colorTrack};`);\n lines.push(` color: ${colorIcons};`);\n lines.push(\"}\");\n lines.push(\"::-webkit-scrollbar-thumb {\");\n lines.push(` background-color: ${colorThumb};`);\n lines.push(\"}\");\n lines.push(\"::-webkit-scrollbar-thumb:hover {\");\n lines.push(` background-color: ${colorThumbHover};`);\n lines.push(\"}\");\n lines.push(\"::-webkit-scrollbar-thumb:active {\");\n lines.push(` background-color: ${colorThumbActive};`);\n lines.push(\"}\");\n lines.push(\"::-webkit-scrollbar-corner {\");\n lines.push(` background-color: ${colorCorner};`);\n lines.push(\"}\");\n if (_utils_platform__WEBPACK_IMPORTED_MODULE_4__.isFirefox) {\n lines.push(\"* {\");\n lines.push(` scrollbar-color: ${colorThumb} ${colorTrack};`);\n lines.push(\"}\");\n }\n return lines.join(\"\\n\");\n}\nfunction shouldIgnoreImage(selectorText, selectors) {\n if (!selectorText || selectors.length === 0) {\n return false;\n }\n if (selectors.some(s => s === \"*\")) {\n return true;\n }\n const ruleSelectors = selectorText.split(/,\\s*/g);\n for (let i = 0; i < selectors.length; i++) {\n const ignoredSelector = selectors[i];\n if (ruleSelectors.some(s => s === ignoredSelector)) {\n return true;\n }\n }\n return false;\n}\nconst imageDetailsCache = new Map();\nconst awaitingForImageLoading = new Map();\nfunction getBgImageModifier(value, rule, ignoreImageSelectors, isCancelled) {\n try {\n const gradients = (0,_utils_parsing__WEBPACK_IMPORTED_MODULE_3__.parseGradient)(value);\n const urls = (0,_utils_text__WEBPACK_IMPORTED_MODULE_5__.getMatches)(_css_rules__WEBPACK_IMPORTED_MODULE_7__.cssURLRegex, value);\n if (urls.length === 0 && gradients.length === 0) {\n return value;\n }\n const getIndices = matches => {\n let index = 0;\n return matches.map(match => {\n const valueIndex = value.indexOf(match, index);\n index = valueIndex + match.length;\n return {\n match,\n index: valueIndex\n };\n });\n };\n const matches = gradients.map(i => ({\n type: \"gradient\",\n ...i\n })).concat(getIndices(urls).map(i => ({\n type: \"url\",\n offset: 0,\n ...i\n }))).sort((a, b) => a.index > b.index ? 1 : -1);\n const getGradientModifier = gradient => {\n const {\n typeGradient,\n match,\n hasComma\n } = gradient;\n const partsRegex = /([^\\(\\),]+(\\([^\\(\\)]*(\\([^\\(\\)]*\\)*[^\\(\\)]*)?\\))?([^\\(\\), ]|( (?!calc)))*),?/g;\n const colorStopRegex = /^(from|color-stop|to)\\(([^\\(\\)]*?,\\s*)?(.*?)\\)$/;\n const parts = (0,_utils_text__WEBPACK_IMPORTED_MODULE_5__.getMatches)(partsRegex, match, 1).map(part => {\n part = part.trim();\n let rgb = (0,_utils_color__WEBPACK_IMPORTED_MODULE_1__.parseColorWithCache)(part);\n if (rgb) {\n return filter => (0,_generators_modify_colors__WEBPACK_IMPORTED_MODULE_0__.modifyGradientColor)(rgb, filter);\n }\n const space = part.lastIndexOf(\" \");\n rgb = (0,_utils_color__WEBPACK_IMPORTED_MODULE_1__.parseColorWithCache)(part.substring(0, space));\n if (rgb) {\n return filter => `${(0,_generators_modify_colors__WEBPACK_IMPORTED_MODULE_0__.modifyGradientColor)(rgb, filter)} ${part.substring(space + 1)}`;\n }\n const colorStopMatch = part.match(colorStopRegex);\n if (colorStopMatch) {\n rgb = (0,_utils_color__WEBPACK_IMPORTED_MODULE_1__.parseColorWithCache)(colorStopMatch[3]);\n if (rgb) {\n return filter => `${colorStopMatch[1]}(${colorStopMatch[2] ? `${colorStopMatch[2]}, ` : \"\"}${(0,_generators_modify_colors__WEBPACK_IMPORTED_MODULE_0__.modifyGradientColor)(rgb, filter)})`;\n }\n }\n return () => part;\n });\n return filter => {\n return `${typeGradient}(${parts.map(modify => modify(filter)).join(\", \")})${hasComma ? \", \" : \"\"}`;\n };\n };\n const getURLModifier = urlValue => {\n if (shouldIgnoreImage(rule.selectorText, ignoreImageSelectors)) {\n return null;\n }\n let url = (0,_css_rules__WEBPACK_IMPORTED_MODULE_7__.getCSSURLValue)(urlValue);\n const isURLEmpty = url.length === 0;\n const {\n parentStyleSheet\n } = rule;\n const baseURL = parentStyleSheet && parentStyleSheet.href ? (0,_css_rules__WEBPACK_IMPORTED_MODULE_7__.getCSSBaseBath)(parentStyleSheet.href) : parentStyleSheet.ownerNode?.baseURI || location.origin;\n url = (0,_utils_url__WEBPACK_IMPORTED_MODULE_6__.getAbsoluteURL)(baseURL, url);\n const absoluteValue = `url(\"${url}\")`;\n return async filter => {\n if (isURLEmpty) {\n return \"url('')\";\n }\n let imageDetails;\n if (imageDetailsCache.has(url)) {\n imageDetails = imageDetailsCache.get(url);\n } else {\n try {\n if (awaitingForImageLoading.has(url)) {\n const awaiters = awaitingForImageLoading.get(url);\n imageDetails = await new Promise(resolve => awaiters.push(resolve));\n if (!imageDetails) {\n return null;\n }\n } else {\n awaitingForImageLoading.set(url, []);\n imageDetails = await (0,_image__WEBPACK_IMPORTED_MODULE_8__.getImageDetails)(url);\n imageDetailsCache.set(url, imageDetails);\n awaitingForImageLoading.get(url).forEach(resolve => resolve(imageDetails));\n awaitingForImageLoading.delete(url);\n }\n if (isCancelled()) {\n return null;\n }\n } catch (err) {\n // logWarn(err);\n if (awaitingForImageLoading.has(url)) {\n awaitingForImageLoading.get(url).forEach(resolve => resolve(null));\n awaitingForImageLoading.delete(url);\n }\n return absoluteValue;\n }\n }\n const bgImageValue = getBgImageValue(imageDetails, filter) || absoluteValue;\n return bgImageValue;\n };\n };\n const getBgImageValue = (imageDetails, filter) => {\n const {\n isDark,\n isLight,\n isTransparent,\n isLarge,\n isTooLarge,\n width\n } = imageDetails;\n let result;\n if (isTooLarge) {\n // logInfo(`Not modifying too large image ${imageDetails.src}`);\n result = `url(\"${imageDetails.src}\")`;\n } else if (isDark && isTransparent && filter.mode === 1 && !isLarge && width > 2) {\n // logInfo(`Inverting dark image ${imageDetails.src}`);\n const inverted = (0,_image__WEBPACK_IMPORTED_MODULE_8__.getFilteredImageDataURL)(imageDetails, {\n ...filter,\n sepia: (0,_utils_math__WEBPACK_IMPORTED_MODULE_2__.clamp)(filter.sepia + 10, 0, 100)\n });\n result = `url(\"${inverted}\")`;\n } else if (isLight && !isTransparent && filter.mode === 1) {\n if (isLarge) {\n // logInfo(`Not modifying light non-transparent large image ${imageDetails.src}`);\n result = \"none\";\n } else {\n // logInfo(`Dimming light image ${imageDetails.src}`);\n const dimmed = (0,_image__WEBPACK_IMPORTED_MODULE_8__.getFilteredImageDataURL)(imageDetails, filter);\n result = `url(\"${dimmed}\")`;\n }\n } else if (filter.mode === 0 && isLight && !isLarge) {\n // logInfo(`Applying filter to image ${imageDetails.src}`);\n const filtered = (0,_image__WEBPACK_IMPORTED_MODULE_8__.getFilteredImageDataURL)(imageDetails, {\n ...filter,\n brightness: (0,_utils_math__WEBPACK_IMPORTED_MODULE_2__.clamp)(filter.brightness - 10, 5, 200),\n sepia: (0,_utils_math__WEBPACK_IMPORTED_MODULE_2__.clamp)(filter.sepia + 10, 0, 100)\n });\n result = `url(\"${filtered}\")`;\n } else {\n // logInfo(`Not modifying too large image ${imageDetails.src}`);\n result = null;\n }\n return result;\n };\n const modifiers = [];\n let matchIndex = 0;\n let prevHasComma = false;\n matches.forEach(({\n type,\n match,\n index,\n typeGradient,\n hasComma,\n offset\n }, i) => {\n const matchStart = index;\n const prefixStart = matchIndex;\n const matchEnd = matchStart + match.length + offset;\n matchIndex = matchEnd;\n\n // Make sure we still push all the unrelated content between gradients and URLs.\n if (prefixStart !== matchStart) {\n if (prevHasComma) {\n modifiers.push(() => {\n let betweenValue = value.substring(prefixStart, matchStart);\n if (betweenValue[0] === \",\") {\n betweenValue = betweenValue.substring(1);\n }\n return betweenValue;\n });\n } else {\n modifiers.push(() => value.substring(prefixStart, matchStart));\n }\n }\n prevHasComma = hasComma || false;\n if (type === \"url\") {\n modifiers.push(getURLModifier(match));\n } else if (type === \"gradient\") {\n modifiers.push(getGradientModifier({\n match,\n index,\n typeGradient: typeGradient,\n hasComma: hasComma || false,\n offset\n }));\n }\n if (i === matches.length - 1) {\n modifiers.push(() => value.substring(matchEnd));\n }\n });\n return filter => {\n const results = modifiers.filter(Boolean).map(modify => modify(filter));\n if (results.some(r => r instanceof Promise)) {\n return Promise.all(results).then(asyncResults => {\n return asyncResults.filter(Boolean).join(\"\");\n });\n }\n // Strip `, initial` suffix. This is some weird computed value by the browser\n const combinedResult = results.join(\"\");\n if (combinedResult.endsWith(\", initial\")) {\n return combinedResult.slice(0, -9);\n }\n return combinedResult;\n };\n } catch (err) {\n // logWarn(`Unable to parse gradient ${value}`, err);\n return null;\n }\n}\nfunction getShadowModifierWithInfo(value) {\n try {\n let index = 0;\n const colorMatches = (0,_utils_text__WEBPACK_IMPORTED_MODULE_5__.getMatches)(/(^|\\s)(?!calc)([a-z]+\\(.+?\\)|#[0-9a-f]+|[a-z]+)(.*?(inset|outset)?($|,))/gi, value, 2);\n let notParsed = 0;\n const modifiers = colorMatches.map((match, i) => {\n const prefixIndex = index;\n const matchIndex = value.indexOf(match, index);\n const matchEnd = matchIndex + match.length;\n index = matchEnd;\n const rgb = (0,_utils_color__WEBPACK_IMPORTED_MODULE_1__.parseColorWithCache)(match);\n if (!rgb) {\n notParsed++;\n return () => value.substring(prefixIndex, matchEnd);\n }\n return filter => `${value.substring(prefixIndex, matchIndex)}${(0,_generators_modify_colors__WEBPACK_IMPORTED_MODULE_0__.modifyShadowColor)(rgb, filter)}${i === colorMatches.length - 1 ? value.substring(matchEnd) : \"\"}`;\n });\n return filter => {\n const modified = modifiers.map(modify => modify(filter)).join(\"\");\n return {\n matchesLength: colorMatches.length,\n unparseableMatchesLength: notParsed,\n result: modified\n };\n };\n } catch (err) {\n // logWarn(`Unable to parse shadow ${value}`, err);\n return null;\n }\n}\nfunction cleanModificationCache() {\n (0,_generators_modify_colors__WEBPACK_IMPORTED_MODULE_0__.clearColorModificationCache)();\n imageDetailsCache.clear();\n (0,_image__WEBPACK_IMPORTED_MODULE_8__.cleanImageProcessingCache)();\n awaitingForImageLoading.clear();\n}\n\n//# sourceURL=webpack://dark-mode/./src/inject/dynamic-theme/modify-css.js?"); |
| 140 |
|
| 141 |
/***/ }), |
| 142 |
|
| 143 |
/***/ "./src/inject/dynamic-theme/style-manager.js": |
| 144 |
/*!***************************************************!*\ |
| 145 |
!*** ./src/inject/dynamic-theme/style-manager.js ***! |
| 146 |
\***************************************************/ |
| 147 |
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { |
| 148 |
|
| 149 |
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ STYLE_SELECTOR: () => (/* binding */ STYLE_SELECTOR),\n/* harmony export */ cleanLoadingLinks: () => (/* binding */ cleanLoadingLinks),\n/* harmony export */ getManageableStyles: () => (/* binding */ getManageableStyles),\n/* harmony export */ manageStyle: () => (/* binding */ manageStyle),\n/* harmony export */ shouldManageStyle: () => (/* binding */ shouldManageStyle)\n/* harmony export */ });\n/* harmony import */ var _utils_array__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../utils/array */ \"./src/utils/array.js\");\n/* harmony import */ var _utils_platform__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../utils/platform */ \"./src/utils/platform.js\");\n/* harmony import */ var _utils_url__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../utils/url */ \"./src/utils/url.js\");\n/* harmony import */ var _utils_dom__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/dom */ \"./src/inject/utils/dom.js\");\n/* harmony import */ var _css_rules__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./css-rules */ \"./src/inject/dynamic-theme/css-rules.js\");\n/* harmony import */ var _stylesheet_modifier__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./stylesheet-modifier */ \"./src/inject/dynamic-theme/stylesheet-modifier.js\");\n\n\n\n\n// import { logInfo, logWarn } from \"../utils/log\";\n\n\nconst rejectorsForLoadingLinks = new Map();\nconst STYLE_SELECTOR = 'style, link[rel*=\"stylesheet\" i]:not([disabled])';\nlet loadingLinkCounter = 0;\n\n// isFontsGoogleApiStyle returns is the given link element is a style from\n// google fonts.\nfunction isFontsGoogleApiStyle(element) {\n if (!element.href) {\n return false;\n }\n try {\n const elementURL = new URL(element.href);\n return elementURL.hostname === \"fonts.googleapis.com\";\n } catch (err) {\n // logInfo(`Couldn't construct ${element.href} as URL`);\n return false;\n }\n}\nfunction shouldManageStyle(element) {\n return (element instanceof HTMLStyleElement || element instanceof SVGStyleElement || element instanceof HTMLLinkElement && Boolean(element.rel) && element.rel.toLowerCase().includes(\"stylesheet\") && Boolean(element.href) && !element.disabled && (_utils_platform__WEBPACK_IMPORTED_MODULE_1__.isFirefox ? !element.href.startsWith(\"moz-extension://\") : true) && !isFontsGoogleApiStyle(element)) && !element.classList.contains(\"adminify\") && element.media.toLowerCase() !== \"print\" && !element.classList.contains(\"stylus\");\n}\nfunction getManageableStyles(node, results = [], deep = true) {\n if (shouldManageStyle(node)) {\n results.push(node);\n } else if (node instanceof Element || _utils_platform__WEBPACK_IMPORTED_MODULE_1__.isShadowDomSupported && node instanceof ShadowRoot || node === document) {\n (0,_utils_array__WEBPACK_IMPORTED_MODULE_0__.forEach)(node.querySelectorAll(STYLE_SELECTOR), style => getManageableStyles(style, results, false));\n if (deep) {\n (0,_utils_dom__WEBPACK_IMPORTED_MODULE_3__.iterateShadowHosts)(node, host => getManageableStyles(host.shadowRoot, results, false));\n }\n }\n return results;\n}\nconst syncStyleSet = new WeakSet();\nconst corsStyleSet = new WeakSet();\nfunction manageStyle(element, {\n update,\n loadingStart,\n loadingEnd\n}) {\n const prevStyles = [];\n let next = element;\n while ((next = next.nextElementSibling) && next.matches(\".adminify\")) {\n prevStyles.push(next);\n }\n let corsCopy = prevStyles.find(el => el.matches(\".adminify--cors\") && !corsStyleSet.has(el)) || null;\n let syncStyle = prevStyles.find(el => el.matches(\".adminify--sync\") && !syncStyleSet.has(el)) || null;\n let corsCopyPositionWatcher = null;\n let syncStylePositionWatcher = null;\n let cancelAsyncOperations = false;\n let isOverrideEmpty = true;\n const sheetModifier = (0,_stylesheet_modifier__WEBPACK_IMPORTED_MODULE_5__.createStyleSheetModifier)();\n const observer = new MutationObserver(() => {\n update();\n });\n const observerOptions = {\n attributes: true,\n childList: true,\n subtree: true,\n characterData: true\n };\n function containsCSSImport() {\n return element instanceof HTMLStyleElement && element.textContent.trim().match(_css_rules__WEBPACK_IMPORTED_MODULE_4__.cssImportRegex);\n }\n\n // It loops trough the cssRules and check for CSSImportRule and their `href`.\n // If the `href` isn't local and doesn't start with the same-origin.\n // We can be ensure that's a cross-origin import\n // And should add a cors-sheet to this element.\n function hasImports(cssRules, checkCrossOrigin) {\n let result = false;\n if (cssRules) {\n let rule;\n cssRulesLoop: for (let i = 0, len = cssRules.length; i < len; i++) {\n rule = cssRules[i];\n if (rule.href) {\n if (checkCrossOrigin) {\n if (!rule.href.startsWith(\"https://fonts.googleapis.com/\") && rule.href.startsWith(\"http\") && !rule.href.startsWith(location.origin)) {\n result = true;\n break cssRulesLoop;\n }\n } else {\n result = true;\n break cssRulesLoop;\n }\n }\n }\n }\n return result;\n }\n function getRulesSync() {\n if (corsCopy) {\n // logInfo(\"[getRulesSync] Using cors-copy.\");\n return corsCopy.sheet.cssRules;\n }\n if (containsCSSImport()) {\n // logInfo(\"[getRulesSync] CSSImport detected.\");\n return null;\n }\n const cssRules = safeGetSheetRules();\n if (element instanceof HTMLLinkElement && !(0,_utils_url__WEBPACK_IMPORTED_MODULE_2__.isRelativeHrefOnAbsolutePath)(element.href) && hasImports(cssRules, false)) {\n // logInfo(\"[getRulesSync] CSSImportRule detected on non-local href.\");\n return null;\n }\n if (hasImports(cssRules, true)) {\n // logInfo(\"[getRulesSync] Cross-Origin CSSImportRule detected.\");\n return null;\n }\n\n // logInfo(\"[getRulesSync] Using cssRules.\");\n // !cssRules && logWarn(\"[getRulesSync] cssRules is null, trying again.\");\n return cssRules;\n }\n function insertStyle() {\n if (corsCopy) {\n if (element.nextSibling !== corsCopy) {\n element.parentNode.insertBefore(corsCopy, element.nextSibling);\n }\n if (corsCopy.nextSibling !== syncStyle) {\n element.parentNode.insertBefore(syncStyle, corsCopy.nextSibling);\n }\n } else if (element.nextSibling !== syncStyle) {\n element.parentNode.insertBefore(syncStyle, element.nextSibling);\n }\n }\n function createSyncStyle() {\n syncStyle = element instanceof SVGStyleElement ? document.createElementNS(\"http://www.w3.org/2000/svg\", \"style\") : document.createElement(\"style\");\n syncStyle.classList.add(\"adminify\");\n syncStyle.classList.add(\"adminify--sync\");\n syncStyle.media = \"screen\";\n if (element.title) {\n syncStyle.title = element.title;\n }\n syncStyleSet.add(syncStyle);\n }\n let isLoadingRules = false;\n let wasLoadingError = false;\n const loadingLinkId = ++loadingLinkCounter;\n async function getRulesAsync() {\n let cssText;\n let cssBasePath;\n if (element instanceof HTMLLinkElement) {\n let [cssRules, accessError] = getRulesOrError();\n if (accessError) {\n // logWarn(accessError);\n }\n if (_utils_platform__WEBPACK_IMPORTED_MODULE_1__.isSafari && !element.sheet || !_utils_platform__WEBPACK_IMPORTED_MODULE_1__.isSafari && !cssRules && !accessError || isStillLoadingError(accessError)) {\n try {\n // logInfo(\n // `Linkelement ${loadingLinkId} is not loaded yet and thus will be await for`,\n // element\n // );\n await linkLoading(element, loadingLinkId);\n } catch (err) {\n // NOTE: Some @import resources can fail,\n // but the style sheet can still be valid.\n // There's no way to get the actual error.\n // logWarn(err);\n wasLoadingError = true;\n }\n if (cancelAsyncOperations) {\n return null;\n }\n [cssRules, accessError] = getRulesOrError();\n if (accessError) {\n // CORS error, cssRules are not accessible\n // for cross-origin resources\n // logWarn(accessError);\n }\n }\n if (cssRules) {\n if (!hasImports(cssRules, false)) {\n return cssRules;\n }\n }\n\n // cssText = await loadText(element.href);\n // cssBasePath = getCSSBaseBath(element.href);\n // if (cancelAsyncOperations) {\n // return null;\n // }\n } else if (containsCSSImport()) {\n cssText = element.textContent.trim();\n cssBasePath = getCSSBaseBath(location.href);\n } else {\n return null;\n }\n if (cssText) {\n // Sometimes cross-origin stylesheets are protected from direct access\n // so need to load CSS text and insert it into style element\n try {\n const fullCSSText = await replaceCSSImports(cssText, cssBasePath);\n corsCopy = createCORSCopy(element, fullCSSText);\n } catch (err) {\n // logWarn(err);\n }\n if (corsCopy) {\n corsCopyPositionWatcher = (0,_utils_dom__WEBPACK_IMPORTED_MODULE_3__.watchForNodePosition)(corsCopy, \"prev-sibling\");\n return corsCopy.sheet.cssRules;\n }\n }\n return null;\n }\n function details(options) {\n const rules = getRulesSync();\n if (!rules) {\n // secondRound is only true after it's\n // has gone trough `details()` & `getRulesAsync` already\n // So that means that `getRulesSync` shouldn't fail.\n // However as a fail-safe to prevent loops, we should\n // return null here and not continue to `getRulesAsync`\n if (options.secondRound) {\n // logWarn(\"Detected dead-lock at details(), returning early to prevent it.\");\n return null;\n }\n if (isLoadingRules || wasLoadingError) {\n return null;\n }\n isLoadingRules = true;\n loadingStart();\n getRulesAsync().then(results => {\n isLoadingRules = false;\n loadingEnd();\n if (results) {\n update();\n }\n }).catch(err => {\n // logWarn(err);\n isLoadingRules = false;\n loadingEnd();\n });\n return null;\n }\n return {\n rules\n };\n }\n let forceRenderStyle = false;\n function render(theme, ignoreImageAnalysis) {\n const rules = getRulesSync();\n if (!rules) {\n return;\n }\n cancelAsyncOperations = false;\n function removeCSSRulesFromSheet(sheet) {\n if (!sheet) {\n return;\n }\n for (let i = sheet.cssRules.length - 1; i >= 0; i--) {\n sheet.deleteRule(i);\n }\n }\n function prepareOverridesSheet() {\n if (!syncStyle) {\n createSyncStyle();\n }\n syncStylePositionWatcher && syncStylePositionWatcher.stop();\n insertStyle();\n\n // Firefox issue: Some websites get CSP warning,\n // when `textContent` is not set (e.g. pypi.org).\n // But for other websites (e.g. facebook.com)\n // some images disappear when `textContent`\n // is initially set to an empty string.\n if (syncStyle.sheet == null) {\n syncStyle.textContent = \"\";\n }\n const sheet = syncStyle.sheet;\n removeCSSRulesFromSheet(sheet);\n if (syncStylePositionWatcher) {\n syncStylePositionWatcher.run();\n } else {\n syncStylePositionWatcher = (0,_utils_dom__WEBPACK_IMPORTED_MODULE_3__.watchForNodePosition)(syncStyle, \"prev-sibling\", () => {\n forceRenderStyle = true;\n buildOverrides();\n });\n }\n return syncStyle.sheet;\n }\n function buildOverrides() {\n const force = forceRenderStyle;\n forceRenderStyle = false;\n sheetModifier.modifySheet({\n prepareSheet: prepareOverridesSheet,\n sourceCSSRules: rules,\n theme,\n ignoreImageAnalysis,\n force,\n isAsyncCancelled: () => cancelAsyncOperations\n });\n isOverrideEmpty = syncStyle.sheet.cssRules.length === 0;\n if (sheetModifier.shouldRebuildStyle()) {\n // \"update\" function schedules rebuilding the style\n // ideally to wait for link loading, because some sites put links any time,\n // but it can be complicated, so waiting for document completion can do the trick\n addReadyStateCompleteListener(() => update());\n }\n }\n buildOverrides();\n }\n function getRulesOrError() {\n try {\n if (element.sheet == null) {\n return [null, null];\n }\n return [element.sheet.cssRules, null];\n } catch (err) {\n return [null, err];\n }\n }\n\n // NOTE: In Firefox, when link is loading,\n // `sheet` property is not null,\n // but `cssRules` access error is thrown\n function isStillLoadingError(error) {\n return error && error.message && error.message.includes(\"loading\");\n }\n\n // Seems like Firefox bug: silent exception is produced\n // without any notice, when accessing <style> CSS rules\n function safeGetSheetRules() {\n const [cssRules, err] = getRulesOrError();\n if (err) {\n // logWarn(err);\n return null;\n }\n return cssRules;\n }\n function watchForSheetChanges() {\n watchForSheetChangesUsingProxy();\n // Sometimes sheet can be null in Firefox and Safari\n // So need to watch for it using rAF\n\n // if (!__THUNDERBIRD__ && !(canOptimizeUsingProxy && element.sheet)) {\n // watchForSheetChangesUsingRAF();\n // }\n }\n\n // let rulesChangeKey = null;\n let rulesCheckFrameId = null;\n\n // function getRulesChangeKey() {\n // const rules = safeGetSheetRules();\n // return rules ? rules.length : null;\n // }\n\n // function didRulesKeyChange() {\n // return getRulesChangeKey() !== rulesChangeKey;\n // }\n\n // function watchForSheetChangesUsingRAF() {\n // rulesChangeKey = getRulesChangeKey();\n // stopWatchingForSheetChangesUsingRAF();\n // const checkForUpdate = () => {\n // if (didRulesKeyChange()) {\n // rulesChangeKey = getRulesChangeKey();\n // update();\n // }\n // if (canOptimizeUsingProxy && element.sheet) {\n // stopWatchingForSheetChangesUsingRAF();\n // return;\n // }\n // rulesCheckFrameId = requestAnimationFrame(checkForUpdate);\n // };\n\n // checkForUpdate();\n // }\n\n function stopWatchingForSheetChangesUsingRAF() {\n // TODO: reove cast once types are updated\n cancelAnimationFrame(rulesCheckFrameId);\n }\n let areSheetChangesPending = false;\n function onSheetChange() {\n canOptimizeUsingProxy = true;\n stopWatchingForSheetChangesUsingRAF();\n if (areSheetChangesPending) {\n return;\n }\n function handleSheetChanges() {\n areSheetChangesPending = false;\n if (cancelAsyncOperations) {\n return;\n }\n update();\n }\n areSheetChangesPending = true;\n if (typeof queueMicrotask === \"function\") {\n queueMicrotask(handleSheetChanges);\n } else {\n requestAnimationFrame(handleSheetChanges);\n }\n }\n function watchForSheetChangesUsingProxy() {\n element.addEventListener(\"__adminify__updateSheet\", onSheetChange, {\n passive: true\n });\n }\n function stopWatchingForSheetChangesUsingProxy() {\n element.removeEventListener(\"__adminify__updateSheet\", onSheetChange);\n }\n function stopWatchingForSheetChanges() {\n stopWatchingForSheetChangesUsingProxy();\n stopWatchingForSheetChangesUsingRAF();\n }\n function pause() {\n observer.disconnect();\n cancelAsyncOperations = true;\n corsCopyPositionWatcher && corsCopyPositionWatcher.stop();\n syncStylePositionWatcher && syncStylePositionWatcher.stop();\n stopWatchingForSheetChanges();\n }\n function destroy() {\n pause();\n (0,_utils_dom__WEBPACK_IMPORTED_MODULE_3__.removeNode)(corsCopy);\n (0,_utils_dom__WEBPACK_IMPORTED_MODULE_3__.removeNode)(syncStyle);\n loadingEnd();\n if (rejectorsForLoadingLinks.has(loadingLinkId)) {\n const reject = rejectorsForLoadingLinks.get(loadingLinkId);\n rejectorsForLoadingLinks.delete(loadingLinkId);\n reject && reject();\n }\n }\n function watch() {\n observer.observe(element, observerOptions);\n if (element instanceof HTMLStyleElement) {\n watchForSheetChanges();\n }\n }\n const maxMoveCount = 10;\n let moveCount = 0;\n function restore() {\n if (!syncStyle) {\n return;\n }\n moveCount++;\n if (moveCount > maxMoveCount) {\n // logWarn(\"Style sheet was moved multiple times\", element);\n return;\n }\n\n // logWarn(\"Restore style\", syncStyle, element);\n insertStyle();\n corsCopyPositionWatcher && corsCopyPositionWatcher.skip();\n syncStylePositionWatcher && syncStylePositionWatcher.skip();\n if (!isOverrideEmpty) {\n forceRenderStyle = true;\n update();\n }\n }\n return {\n details,\n render,\n pause,\n destroy,\n watch,\n restore\n };\n}\nfunction cleanLoadingLinks() {\n rejectorsForLoadingLinks.clear();\n}\n\n//# sourceURL=webpack://dark-mode/./src/inject/dynamic-theme/style-manager.js?"); |
| 150 |
|
| 151 |
/***/ }), |
| 152 |
|
| 153 |
/***/ "./src/inject/dynamic-theme/stylesheet-modifier.js": |
| 154 |
/*!*********************************************************!*\ |
| 155 |
!*** ./src/inject/dynamic-theme/stylesheet-modifier.js ***! |
| 156 |
\*********************************************************/ |
| 157 |
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { |
| 158 |
|
| 159 |
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ createStyleSheetModifier: () => (/* binding */ createStyleSheetModifier)\n/* harmony export */ });\n/* harmony import */ var _utils_throttle__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../utils/throttle */ \"./src/utils/throttle.js\");\n/* harmony import */ var _css_rules__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./css-rules */ \"./src/inject/dynamic-theme/css-rules.js\");\n/* harmony import */ var _modify_css__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./modify-css */ \"./src/inject/dynamic-theme/modify-css.js\");\n/* harmony import */ var _variables__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./variables */ \"./src/inject/dynamic-theme/variables.js\");\n\n\n\n\nconst themeCacheKeys = [\"mode\", \"brightness\", \"contrast\", \"grayscale\", \"sepia\", \"darkSchemeBackgroundColor\", \"darkSchemeTextColor\", \"lightSchemeBackgroundColor\", \"lightSchemeTextColor\"];\nfunction getThemeKey(theme) {\n let resultKey = \"\";\n themeCacheKeys.forEach(key => {\n resultKey += `${key}:${theme[key]};`;\n });\n return resultKey;\n}\nconst asyncQueue = (0,_utils_throttle__WEBPACK_IMPORTED_MODULE_0__.createAsyncTasksQueue)();\nfunction createStyleSheetModifier() {\n let renderId = 0;\n const rulesTextCache = new Set();\n const rulesModCache = new Map();\n const varTypeChangeCleaners = new Set();\n let prevFilterKey = null;\n let hasNonLoadedLink = false;\n let wasRebuilt = false;\n function shouldRebuildStyle() {\n return hasNonLoadedLink && !wasRebuilt;\n }\n function modifySheet(options) {\n const rules = options.sourceCSSRules;\n const {\n theme,\n ignoreImageAnalysis,\n force,\n prepareSheet,\n isAsyncCancelled\n } = options;\n let rulesChanged = rulesModCache.size === 0;\n const notFoundCacheKeys = new Set(rulesModCache.keys());\n const themeKey = getThemeKey(theme);\n const themeChanged = themeKey !== prevFilterKey;\n if (hasNonLoadedLink) {\n wasRebuilt = true;\n }\n const modRules = [];\n (0,_css_rules__WEBPACK_IMPORTED_MODULE_1__.iterateCSSRules)(rules, rule => {\n let cssText = rule.cssText;\n let textDiffersFromPrev = false;\n notFoundCacheKeys.delete(cssText);\n if (rule.parentRule instanceof CSSMediaRule) {\n cssText += `;${rule.parentRule.media.mediaText}`;\n }\n if (!rulesTextCache.has(cssText)) {\n rulesTextCache.add(cssText);\n textDiffersFromPrev = true;\n }\n if (textDiffersFromPrev) {\n rulesChanged = true;\n } else {\n modRules.push(rulesModCache.get(cssText));\n return;\n }\n\n // A very specific case to skip. This causes a lot of calls to `getModifiableCSSDeclaration`\n // and currently contributes nothing in real-world case.\n // TODO: Allow `setRule` to throw a exception when we're modifying SVGs namespace styles.\n if (rule.style.all === \"revert\") {\n return;\n }\n const modDecs = [];\n rule.style && (0,_css_rules__WEBPACK_IMPORTED_MODULE_1__.iterateCSSDeclarations)(rule.style, (property, value) => {\n const mod = (0,_modify_css__WEBPACK_IMPORTED_MODULE_2__.getModifiableCSSDeclaration)(property, value, rule, _variables__WEBPACK_IMPORTED_MODULE_3__.variablesStore, ignoreImageAnalysis, isAsyncCancelled);\n if (mod) {\n modDecs.push(mod);\n }\n });\n let modRule = null;\n if (modDecs.length > 0) {\n const parentRule = rule.parentRule;\n modRule = {\n selector: rule.selectorText,\n declarations: modDecs,\n parentRule\n };\n modRules.push(modRule);\n }\n rulesModCache.set(cssText, modRule);\n }, () => {\n hasNonLoadedLink = true;\n });\n notFoundCacheKeys.forEach(key => {\n rulesTextCache.delete(key);\n rulesModCache.delete(key);\n });\n prevFilterKey = themeKey;\n if (!force && !rulesChanged && !themeChanged) {\n return;\n }\n renderId++;\n function setRule(target, index, rule) {\n const {\n selector,\n declarations\n } = rule;\n const getDeclarationText = dec => {\n const {\n property,\n value,\n important,\n sourceValue\n } = dec;\n return `${property}: ${value == null ? sourceValue : value}${important ? \" !important\" : \"\"};`;\n };\n let cssRulesText = \"\";\n declarations.forEach(declarations => {\n cssRulesText += `${getDeclarationText(declarations)} `;\n });\n const ruleText = `${selector} { ${cssRulesText} }`;\n target.insertRule(ruleText, index);\n }\n const asyncDeclarations = new Map();\n const varDeclarations = new Map();\n let asyncDeclarationCounter = 0;\n let varDeclarationCounter = 0;\n const rootReadyGroup = {\n rule: null,\n rules: [],\n isGroup: true\n };\n const groupRefs = new WeakMap();\n function getGroup(rule) {\n if (rule == null) {\n return rootReadyGroup;\n }\n if (groupRefs.has(rule)) {\n return groupRefs.get(rule);\n }\n const group = {\n rule,\n rules: [],\n isGroup: true\n };\n groupRefs.set(rule, group);\n const parentGroup = getGroup(rule.parentRule);\n parentGroup.rules.push(group);\n return group;\n }\n varTypeChangeCleaners.forEach(clear => clear());\n varTypeChangeCleaners.clear();\n modRules.filter(r => r).forEach(({\n selector,\n declarations,\n parentRule\n }) => {\n const group = getGroup(parentRule);\n const readyStyleRule = {\n selector,\n declarations: [],\n isGroup: false\n };\n const readyDeclarations = readyStyleRule.declarations;\n group.rules.push(readyStyleRule);\n function handleAsyncDeclaration(property, modified, important, sourceValue) {\n const asyncKey = ++asyncDeclarationCounter;\n const asyncDeclaration = {\n property,\n value: null,\n important,\n asyncKey,\n sourceValue\n };\n readyDeclarations.push(asyncDeclaration);\n const currentRenderId = renderId;\n modified.then(asyncValue => {\n if (!asyncValue || isAsyncCancelled() || currentRenderId !== renderId) {\n return;\n }\n asyncDeclaration.value = asyncValue;\n asyncQueue.add(() => {\n if (isAsyncCancelled() || currentRenderId !== renderId) {\n return;\n }\n rebuildAsyncRule(asyncKey);\n });\n });\n }\n function handleVarDeclarations(property, modified, important, sourceValue) {\n const {\n declarations: varDecs,\n onTypeChange\n } = modified;\n const varKey = ++varDeclarationCounter;\n const currentRenderId = renderId;\n const initialIndex = readyDeclarations.length;\n let oldDecs = [];\n if (varDecs.length === 0) {\n const tempDec = {\n property,\n value: sourceValue,\n important,\n sourceValue,\n varKey\n };\n readyDeclarations.push(tempDec);\n oldDecs = [tempDec];\n }\n varDecs.forEach(mod => {\n if (mod.value instanceof Promise) {\n handleAsyncDeclaration(mod.property, mod.value, important, sourceValue);\n } else {\n const readyDec = {\n property: mod.property,\n value: mod.value,\n important,\n sourceValue,\n varKey\n };\n readyDeclarations.push(readyDec);\n oldDecs.push(readyDec);\n }\n });\n onTypeChange.addListener(newDecs => {\n if (isAsyncCancelled() || currentRenderId !== renderId) {\n return;\n }\n const readyVarDecs = newDecs.map(mod => {\n return {\n property: mod.property,\n value: mod.value,\n important,\n sourceValue,\n varKey\n };\n });\n // TODO: Don't search for index, store some way or use Linked List.\n const index = readyDeclarations.indexOf(oldDecs[0], initialIndex);\n readyDeclarations.splice(index, oldDecs.length, ...readyVarDecs);\n oldDecs = readyVarDecs;\n rebuildVarRule(varKey);\n });\n varTypeChangeCleaners.add(() => onTypeChange.removeListeners());\n }\n declarations.forEach(({\n property,\n value,\n important,\n sourceValue\n }) => {\n if (typeof value === \"function\") {\n const modified = value(theme);\n if (modified instanceof Promise) {\n handleAsyncDeclaration(property, modified, important, sourceValue);\n } else if (property.startsWith(\"--\")) {\n handleVarDeclarations(property, modified, important, sourceValue);\n } else {\n readyDeclarations.push({\n property,\n value: modified,\n important,\n sourceValue\n });\n }\n } else {\n readyDeclarations.push({\n property,\n value,\n important,\n sourceValue\n });\n }\n });\n });\n const sheet = prepareSheet();\n function buildStyleSheet() {\n function createTarget(group, parent) {\n const {\n rule\n } = group;\n if (rule instanceof CSSMediaRule) {\n const {\n media\n } = rule;\n const index = parent.cssRules.length;\n parent.insertRule(`@media ${media.mediaText} {}`, index);\n return parent.cssRules[index];\n }\n return parent;\n }\n function iterateReadyRules(group, target, styleIterator) {\n group.rules.forEach(r => {\n if (r.isGroup) {\n const t = createTarget(r, target);\n iterateReadyRules(r, t, styleIterator);\n } else {\n styleIterator(r, target);\n }\n });\n }\n iterateReadyRules(rootReadyGroup, sheet, (rule, target) => {\n const index = target.cssRules.length;\n rule.declarations.forEach(({\n asyncKey,\n varKey\n }) => {\n if (asyncKey != null) {\n asyncDeclarations.set(asyncKey, {\n rule,\n target,\n index\n });\n }\n if (varKey != null) {\n varDeclarations.set(varKey, {\n rule,\n target,\n index\n });\n }\n });\n setRule(target, index, rule);\n });\n }\n function rebuildAsyncRule(key) {\n const {\n rule,\n target,\n index\n } = asyncDeclarations.get(key);\n target.deleteRule(index);\n setRule(target, index, rule);\n asyncDeclarations.delete(key);\n }\n function rebuildVarRule(key) {\n const {\n rule,\n target,\n index\n } = varDeclarations.get(key);\n target.deleteRule(index);\n setRule(target, index, rule);\n }\n buildStyleSheet();\n }\n return {\n modifySheet,\n shouldRebuildStyle\n };\n}\n\n//# sourceURL=webpack://dark-mode/./src/inject/dynamic-theme/stylesheet-modifier.js?"); |
| 160 |
|
| 161 |
/***/ }), |
| 162 |
|
| 163 |
/***/ "./src/inject/dynamic-theme/variables.js": |
| 164 |
/*!***********************************************!*\ |
| 165 |
!*** ./src/inject/dynamic-theme/variables.js ***! |
| 166 |
\***********************************************/ |
| 167 |
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { |
| 168 |
|
| 169 |
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ VariablesStore: () => (/* binding */ VariablesStore),\n/* harmony export */ replaceCSSVariablesNames: () => (/* binding */ replaceCSSVariablesNames),\n/* harmony export */ variablesStore: () => (/* binding */ variablesStore)\n/* harmony export */ });\n/* harmony import */ var _generators_modify_colors__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../generators/modify-colors */ \"./src/generators/modify-colors.js\");\n/* harmony import */ var _utils_text__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../utils/text */ \"./src/utils/text.js\");\n/* harmony import */ var _css_rules__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./css-rules */ \"./src/inject/dynamic-theme/css-rules.js\");\n/* harmony import */ var _modify_css__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./modify-css */ \"./src/inject/dynamic-theme/modify-css.js\");\n/* harmony import */ var _utils_color__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../utils/color */ \"./src/utils/color.js\");\n\n\n\n\n\nconst VAR_TYPE_BGCOLOR = 1 << 0;\nconst VAR_TYPE_TEXTCOLOR = 1 << 1;\nconst VAR_TYPE_BORDERCOLOR = 1 << 2;\nconst VAR_TYPE_BGIMG = 1 << 3;\nclass VariablesStore {\n varTypes = new Map();\n rulesQueue = [];\n definedVars = new Set();\n varRefs = new Map();\n unknownColorVars = new Set();\n unknownBgVars = new Set();\n undefinedVars = new Set();\n initialVarTypes = new Map();\n changedTypeVars = new Set();\n typeChangeSubscriptions = new Map();\n unstableVarValues = new Map();\n clear() {\n this.varTypes.clear();\n this.rulesQueue.splice(0);\n this.definedVars.clear();\n this.varRefs.clear();\n this.unknownColorVars.clear();\n this.unknownBgVars.clear();\n this.undefinedVars.clear();\n this.initialVarTypes.clear();\n this.changedTypeVars.clear();\n this.typeChangeSubscriptions.clear();\n this.unstableVarValues.clear();\n }\n isVarType(varName, typeNum) {\n return this.varTypes.has(varName) && (this.varTypes.get(varName) & typeNum) > 0;\n }\n addRulesForMatching(rules) {\n this.rulesQueue.push(rules);\n }\n matchVariablesAndDependants() {\n this.changedTypeVars.clear();\n this.initialVarTypes = new Map(this.varTypes);\n this.collectRootVariables();\n this.collectVariablesAndVarDep(this.rulesQueue);\n this.rulesQueue.splice(0);\n this.collectRootVarDependants();\n this.varRefs.forEach((refs, v) => {\n refs.forEach(r => {\n if (this.varTypes.has(v)) {\n this.resolveVariableType(r, this.varTypes.get(v));\n }\n });\n });\n this.unknownColorVars.forEach(v => {\n if (this.unknownBgVars.has(v)) {\n this.unknownColorVars.delete(v);\n this.unknownBgVars.delete(v);\n this.resolveVariableType(v, VAR_TYPE_BGCOLOR);\n } else if (this.isVarType(v, VAR_TYPE_BGCOLOR | VAR_TYPE_TEXTCOLOR | VAR_TYPE_BORDERCOLOR)) {\n this.unknownColorVars.delete(v);\n } else {\n this.undefinedVars.add(v);\n }\n });\n this.unknownBgVars.forEach(v => {\n const hasColor = this.findVarRef(v, ref => {\n return this.unknownColorVars.has(ref) || this.isVarType(ref, VAR_TYPE_TEXTCOLOR | VAR_TYPE_BORDERCOLOR);\n }) != null;\n if (hasColor) {\n this.itarateVarRefs(v, ref => {\n this.resolveVariableType(ref, VAR_TYPE_BGCOLOR);\n });\n } else if (this.isVarType(v, VAR_TYPE_BGCOLOR | VAR_TYPE_BGIMG)) {\n this.unknownBgVars.delete(v);\n } else {\n this.undefinedVars.add(v);\n }\n });\n this.changedTypeVars.forEach(varName => {\n if (this.typeChangeSubscriptions.has(varName)) {\n this.typeChangeSubscriptions.get(varName).forEach(callback => {\n callback();\n });\n }\n });\n this.changedTypeVars.clear();\n }\n getModifierForVariable(options) {\n return theme => {\n const {\n varName,\n sourceValue,\n rule,\n ignoredImgSelectors,\n isCancelled\n } = options;\n const getDeclarations = () => {\n const declarations = [];\n const addModifiedValue = (typeNum, varNameWrapper, colorModifier) => {\n if (!this.isVarType(varName, typeNum)) {\n return;\n }\n const property = varNameWrapper(varName);\n let modifiedValue;\n if (isVarDependant(sourceValue)) {\n if (isConstructedColorVar(sourceValue)) {\n let value = insertVarValues(sourceValue, this.unstableVarValues);\n if (!value) {\n value = typeNum === VAR_TYPE_BGCOLOR ? \"#ffffff\" : \"#000000\";\n }\n modifiedValue = colorModifier(value, theme);\n } else {\n modifiedValue = replaceCSSVariablesNames(sourceValue, v => varNameWrapper(v), fallback => colorModifier(fallback, theme));\n }\n } else {\n modifiedValue = colorModifier(sourceValue, theme);\n }\n declarations.push({\n property,\n value: modifiedValue\n });\n };\n addModifiedValue(VAR_TYPE_BGCOLOR, wrapBgColorVariableName, tryModifyBgColor);\n addModifiedValue(VAR_TYPE_TEXTCOLOR, wrapTextColorVariableName, tryModifyTextColor);\n addModifiedValue(VAR_TYPE_BORDERCOLOR, wrapBorderColorVariableName, tryModifyBorderColor);\n if (this.isVarType(varName, VAR_TYPE_BGIMG)) {\n const property = wrapBgImgVariableName(varName);\n let modifiedValue = sourceValue;\n if (isVarDependant(sourceValue)) {\n modifiedValue = replaceCSSVariablesNames(sourceValue, v => wrapBgColorVariableName(v), fallback => tryModifyBgColor(fallback, theme));\n }\n const bgModifier = (0,_modify_css__WEBPACK_IMPORTED_MODULE_3__.getBgImageModifier)(modifiedValue, rule, ignoredImgSelectors, isCancelled);\n modifiedValue = typeof bgModifier === \"function\" ? bgModifier(theme) : bgModifier;\n declarations.push({\n property,\n value: modifiedValue\n });\n }\n return declarations;\n };\n const callbacks = new Set();\n const addListener = onTypeChange => {\n const callback = () => {\n const decs = getDeclarations();\n onTypeChange(decs);\n };\n callbacks.add(callback);\n this.subscribeForVarTypeChange(varName, callback);\n };\n const removeListeners = () => {\n callbacks.forEach(callback => {\n this.unsubscribeFromVariableTypeChanges(varName, callback);\n });\n };\n return {\n declarations: getDeclarations(),\n onTypeChange: {\n addListener,\n removeListeners\n }\n };\n };\n }\n getModifierForVarDependant(property, sourceValue) {\n // TODO(gusted): This condition is incorrect, as the sourceValue still contains a variable.\n // Simply replacing it with some definition is incorrect as variables are element-independent.\n // Fully handling this requires having a function that gives the variable's value given an\n // element's position in the DOM, but that's quite computationally hard to facilitate. We'll\n // probably just handle edge-cases like `rgb(22 163 74/var(--tb-bg-opacity)` and hope that\n // lowering the opacity is enough.\n if (sourceValue.match(/^\\s*(rgb|hsl)a?\\(/)) {\n const isBg = property.startsWith(\"background\");\n const isText = isTextColorProperty(property);\n return theme => {\n let value = insertVarValues(sourceValue, this.unstableVarValues);\n if (!value) {\n value = isBg ? \"#ffffff\" : \"#000000\";\n }\n const modifier = isBg ? tryModifyBgColor : isText ? tryModifyTextColor : tryModifyBorderColor;\n return modifier(value, theme);\n };\n }\n if (property === \"background-color\") {\n return theme => {\n return replaceCSSVariablesNames(sourceValue, v => wrapBgColorVariableName(v), fallback => tryModifyBgColor(fallback, theme));\n };\n }\n if (isTextColorProperty(property)) {\n return theme => {\n return replaceCSSVariablesNames(sourceValue, v => wrapTextColorVariableName(v), fallback => tryModifyTextColor(fallback, theme));\n };\n }\n if (property === \"background\" || property === \"background-image\" || property === \"box-shadow\") {\n return theme => {\n const unknownVars = new Set();\n const modify = () => {\n const variableReplaced = replaceCSSVariablesNames(sourceValue, v => {\n if (this.isVarType(v, VAR_TYPE_BGCOLOR)) {\n return wrapBgColorVariableName(v);\n }\n if (this.isVarType(v, VAR_TYPE_BGIMG)) {\n return wrapBgImgVariableName(v);\n }\n unknownVars.add(v);\n return v;\n }, fallback => tryModifyBgColor(fallback, theme));\n // Check if the property is box-shadow and if so, do a pass-through to modify the shadow.\n if (property === \"box-shadow\") {\n const shadowModifier = (0,_modify_css__WEBPACK_IMPORTED_MODULE_3__.getShadowModifierWithInfo)(variableReplaced);\n const modifiedShadow = shadowModifier(theme);\n if (modifiedShadow.unparseableMatchesLength !== modifiedShadow.matchesLength) {\n return modifiedShadow.result;\n }\n }\n return variableReplaced;\n };\n const modified = modify();\n if (unknownVars.size > 0) {\n return new Promise(resolve => {\n const firstUnknownVar = unknownVars.values().next().value;\n const callback = () => {\n this.unsubscribeFromVariableTypeChanges(firstUnknownVar, callback);\n const newValue = modify();\n resolve(newValue);\n };\n this.subscribeForVarTypeChange(firstUnknownVar, callback);\n });\n }\n return modified;\n };\n }\n if (property.startsWith(\"border\") || property.startsWith(\"outline\")) {\n return theme => {\n return replaceCSSVariablesNames(sourceValue, v => wrapBorderColorVariableName(v), fallback => tryModifyBorderColor(fallback, theme));\n };\n }\n return null;\n }\n subscribeForVarTypeChange(varName, callback) {\n if (!this.typeChangeSubscriptions.has(varName)) {\n this.typeChangeSubscriptions.set(varName, new Set());\n }\n const rootStore = this.typeChangeSubscriptions.get(varName);\n if (!rootStore.has(callback)) {\n rootStore.add(callback);\n }\n }\n unsubscribeFromVariableTypeChanges(varName, callback) {\n if (this.typeChangeSubscriptions.has(varName)) {\n this.typeChangeSubscriptions.get(varName).delete(callback);\n }\n }\n\n // Because of the similar expensive task between the old `collectVariables`\n // and `collectVarDepandant`, we only want to do it once.\n // This function should only do the same expensive task once\n // and ensure that the result comes to the correct task.\n // The task is either `inspectVariable` or `inspectVarDependant`.\n collectVariablesAndVarDep(ruleList) {\n ruleList.forEach(rules => {\n (0,_css_rules__WEBPACK_IMPORTED_MODULE_2__.iterateCSSRules)(rules, rule => {\n rule.style && (0,_css_rules__WEBPACK_IMPORTED_MODULE_2__.iterateCSSDeclarations)(rule.style, (property, value) => {\n if (isVariable(property)) {\n this.inspectVariable(property, value);\n }\n if (isVarDependant(value)) {\n this.inspectVarDependant(property, value);\n }\n });\n });\n });\n }\n collectRootVariables() {\n (0,_css_rules__WEBPACK_IMPORTED_MODULE_2__.iterateCSSDeclarations)(document.documentElement.style, (property, value) => {\n if (isVariable(property)) {\n this.inspectVariable(property, value);\n }\n });\n }\n inspectVariable(varName, value) {\n this.unstableVarValues.set(varName, value);\n if (isVarDependant(value) && isConstructedColorVar(value)) {\n this.unknownColorVars.add(varName);\n this.definedVars.add(varName);\n }\n if (this.definedVars.has(varName)) {\n return;\n }\n this.definedVars.add(varName);\n\n // Check if the value is either a raw value or a value that can be parsed\n // e.g. rgb, hsl.\n const isColor = rawValueRegex.test(value) || (0,_utils_color__WEBPACK_IMPORTED_MODULE_4__.parseColorWithCache)(value);\n if (isColor) {\n this.unknownColorVars.add(varName);\n } else if (value.includes(\"url(\") || value.includes(\"linear-gradient(\") || value.includes(\"radial-gradient(\")) {\n this.resolveVariableType(varName, VAR_TYPE_BGIMG);\n }\n }\n resolveVariableType(varName, typeNum) {\n const initialType = this.initialVarTypes.get(varName) || 0;\n const currentType = this.varTypes.get(varName) || 0;\n const newType = currentType | typeNum;\n this.varTypes.set(varName, newType);\n if (newType !== initialType || this.undefinedVars.has(varName)) {\n this.changedTypeVars.add(varName);\n this.undefinedVars.delete(varName);\n }\n this.unknownColorVars.delete(varName);\n this.unknownBgVars.delete(varName);\n }\n collectRootVarDependants() {\n (0,_css_rules__WEBPACK_IMPORTED_MODULE_2__.iterateCSSDeclarations)(document.documentElement.style, (property, value) => {\n if (isVarDependant(value)) {\n this.inspectVarDependant(property, value);\n }\n });\n }\n inspectVarDependant(property, value) {\n if (isVariable(property)) {\n this.iterateVarDeps(value, ref => {\n if (!this.varRefs.has(property)) {\n this.varRefs.set(property, new Set());\n }\n this.varRefs.get(property).add(ref);\n });\n } else if (property === \"background-color\" || property === \"box-shadow\") {\n this.iterateVarDeps(value, v => this.resolveVariableType(v, VAR_TYPE_BGCOLOR));\n } else if (isTextColorProperty(property)) {\n this.iterateVarDeps(value, v => this.resolveVariableType(v, VAR_TYPE_TEXTCOLOR));\n } else if (property.startsWith(\"border\") || property.startsWith(\"outline\")) {\n this.iterateVarDeps(value, v => this.resolveVariableType(v, VAR_TYPE_BORDERCOLOR));\n } else if (property === \"background\" || property === \"background-image\") {\n this.iterateVarDeps(value, v => {\n if (this.isVarType(v, VAR_TYPE_BGCOLOR | VAR_TYPE_BGIMG)) {\n return;\n }\n const isBgColor = this.findVarRef(v, ref => {\n return this.unknownColorVars.has(ref) || this.isVarType(ref, VAR_TYPE_TEXTCOLOR | VAR_TYPE_BORDERCOLOR);\n }) != null;\n this.itarateVarRefs(v, ref => {\n if (isBgColor) {\n this.resolveVariableType(ref, VAR_TYPE_BGCOLOR);\n } else {\n this.unknownBgVars.add(ref);\n }\n });\n });\n }\n }\n iterateVarDeps(value, iterator) {\n const varDeps = new Set();\n iterateVarDependencies(value, v => varDeps.add(v));\n varDeps.forEach(v => iterator(v));\n }\n findVarRef(varName, iterator, stack = new Set()) {\n if (stack.has(varName)) {\n return null;\n }\n stack.add(varName);\n const result = iterator(varName);\n if (result) {\n return varName;\n }\n const refs = this.varRefs.get(varName);\n if (!refs || refs.size === 0) {\n return null;\n }\n for (const ref of refs) {\n const found = this.findVarRef(ref, iterator, stack);\n if (found) {\n return found;\n }\n }\n return null;\n }\n itarateVarRefs(varName, iterator) {\n this.findVarRef(varName, ref => {\n iterator(ref);\n return false;\n });\n }\n setOnRootVariableChange(callback) {\n this.onRootVariableDefined = callback;\n }\n putRootVars(styleElement, theme) {\n const sheet = styleElement.sheet;\n if (sheet.cssRules.length > 0) {\n sheet.deleteRule(0);\n }\n const declarations = new Map();\n (0,_css_rules__WEBPACK_IMPORTED_MODULE_2__.iterateCSSDeclarations)(document.documentElement.style, (property, value) => {\n if (isVariable(property)) {\n if (this.isVarType(property, VAR_TYPE_BGCOLOR)) {\n declarations.set(wrapBgColorVariableName(property), tryModifyBgColor(value, theme));\n }\n if (this.isVarType(property, VAR_TYPE_TEXTCOLOR)) {\n declarations.set(wrapTextColorVariableName(property), tryModifyTextColor(value, theme));\n }\n if (this.isVarType(property, VAR_TYPE_BORDERCOLOR)) {\n declarations.set(wrapBorderColorVariableName(property), tryModifyBorderColor(value, theme));\n }\n this.subscribeForVarTypeChange(property, this.onRootVariableDefined);\n }\n });\n const cssLines = [];\n cssLines.push(\":root {\");\n for (const [property, value] of declarations) {\n cssLines.push(` ${property}: ${value};`);\n }\n cssLines.push(\"}\");\n const cssText = cssLines.join(\"\\n\");\n sheet.insertRule(cssText);\n }\n}\nconst variablesStore = new VariablesStore();\nfunction getVariableRange(input, searchStart = 0) {\n const start = input.indexOf(\"var(\", searchStart);\n if (start >= 0) {\n const range = (0,_utils_text__WEBPACK_IMPORTED_MODULE_1__.getParenthesesRange)(input, start + 3);\n if (range) {\n return {\n start,\n end: range.end\n };\n }\n }\n return null;\n}\nfunction getVariablesMatches(input) {\n const ranges = [];\n let i = 0;\n let range;\n while (range = getVariableRange(input, i)) {\n const {\n start,\n end\n } = range;\n ranges.push({\n start,\n end,\n value: input.substring(start, end)\n });\n i = range.end + 1;\n }\n return ranges;\n}\nfunction replaceVariablesMatches(input, replacer) {\n const matches = getVariablesMatches(input);\n const matchesCount = matches.length;\n if (matchesCount === 0) {\n return input;\n }\n const inputLength = input.length;\n const replacements = matches.map(m => replacer(m.value));\n const parts = [];\n parts.push(input.substring(0, matches[0].start));\n for (let i = 0; i < matchesCount; i++) {\n parts.push(replacements[i]);\n const start = matches[i].end;\n const end = i < matchesCount - 1 ? matches[i + 1].start : inputLength;\n parts.push(input.substring(start, end));\n }\n return parts.join(\"\");\n}\nfunction getVariableNameAndFallback(match) {\n const commaIndex = match.indexOf(\",\");\n let name;\n let fallback;\n if (commaIndex >= 0) {\n name = match.substring(4, commaIndex).trim();\n fallback = match.substring(commaIndex + 1, match.length - 1).trim();\n } else {\n name = match.substring(4, match.length - 1).trim();\n fallback = \"\";\n }\n return {\n name,\n fallback\n };\n}\nfunction replaceCSSVariablesNames(value, nameReplacer, fallbackReplacer) {\n const matchReplacer = match => {\n const {\n name,\n fallback\n } = getVariableNameAndFallback(match);\n const newName = nameReplacer(name);\n if (!fallback) {\n return `var(${newName})`;\n }\n let newFallback;\n if (isVarDependant(fallback)) {\n newFallback = replaceCSSVariablesNames(fallback, nameReplacer, fallbackReplacer);\n } else if (fallbackReplacer) {\n newFallback = fallbackReplacer(fallback);\n } else {\n newFallback = fallback;\n }\n return `var(${newName}, ${newFallback})`;\n };\n return replaceVariablesMatches(value, matchReplacer);\n}\nfunction iterateVarDependencies(value, iterator) {\n replaceCSSVariablesNames(value, varName => {\n iterator(varName);\n return varName;\n });\n}\nfunction wrapBgColorVariableName(name) {\n return `--adminify-bg${name}`;\n}\nfunction wrapTextColorVariableName(name) {\n return `--adminify-text${name}`;\n}\nfunction wrapBorderColorVariableName(name) {\n return `--adminify-border${name}`;\n}\nfunction wrapBgImgVariableName(name) {\n return `--adminify-bgimg${name}`;\n}\nfunction isVariable(property) {\n return property.startsWith(\"--\");\n}\nfunction isVarDependant(value) {\n return value.includes(\"var(\");\n}\nfunction isConstructedColorVar(value) {\n return value.match(/^\\s*(rgb|hsl)a?\\(/);\n}\nfunction isTextColorProperty(property) {\n return property === \"color\" || property === \"caret-color\" || property === \"-webkit-text-fill-color\";\n}\n\n// ex. 131,123,132 | 1,341, 122\nconst rawValueRegex = /^\\d{1,3}, ?\\d{1,3}, ?\\d{1,3}$/;\nfunction parseRawValue(color) {\n if (rawValueRegex.test(color)) {\n // Convert the raw value into a useable rgb(...) value, such that it can\n // be properly used with other functions that expect such value.\n const splitted = color.split(\",\");\n let resultInRGB = \"rgb(\";\n splitted.forEach(number => {\n resultInRGB += `${number.trim()}, `;\n });\n resultInRGB = resultInRGB.substring(0, resultInRGB.length - 2);\n resultInRGB += \")\";\n return {\n isRaw: true,\n color: resultInRGB\n };\n }\n return {\n isRaw: false,\n color: color\n };\n}\nfunction handleRawValue(color, theme, modifyFunction) {\n const {\n isRaw,\n color: newColor\n } = parseRawValue(color);\n const rgb = (0,_utils_color__WEBPACK_IMPORTED_MODULE_4__.parseColorWithCache)(newColor);\n if (rgb) {\n const outputColor = modifyFunction(rgb, theme);\n\n // If it's raw, we need to convert it back to the \"raw\" format.\n if (isRaw) {\n // This should technically never fail(returning an empty string),\n // but just to be safe, we will return outputColor.\n const outputInRGB = (0,_utils_color__WEBPACK_IMPORTED_MODULE_4__.parseColorWithCache)(outputColor);\n return outputInRGB ? `${outputInRGB.r}, ${outputInRGB.g}, ${outputInRGB.b}` : outputColor;\n }\n return outputColor;\n }\n return newColor;\n}\nfunction tryModifyBgColor(color, theme) {\n return handleRawValue(color, theme, _generators_modify_colors__WEBPACK_IMPORTED_MODULE_0__.modifyBackgroundColor);\n}\nfunction tryModifyTextColor(color, theme) {\n return handleRawValue(color, theme, _generators_modify_colors__WEBPACK_IMPORTED_MODULE_0__.modifyForegroundColor);\n}\nfunction tryModifyBorderColor(color, theme) {\n return handleRawValue(color, theme, _generators_modify_colors__WEBPACK_IMPORTED_MODULE_0__.modifyBorderColor);\n}\nfunction insertVarValues(source, varValues, stack = new Set()) {\n let containsUnresolvedVar = false;\n const matchReplacer = match => {\n const {\n name,\n fallback\n } = getVariableNameAndFallback(match);\n if (stack.has(name)) {\n containsUnresolvedVar = true;\n return null;\n }\n stack.add(name);\n const varValue = varValues.get(name) || fallback;\n let inserted = null;\n if (varValue) {\n if (isVarDependant(varValue)) {\n inserted = insertVarValues(varValue, varValues, stack);\n } else {\n inserted = varValue;\n }\n }\n if (!inserted) {\n containsUnresolvedVar = true;\n return null;\n }\n return inserted;\n };\n const replaced = replaceVariablesMatches(source, matchReplacer);\n if (containsUnresolvedVar) {\n return null;\n }\n return replaced;\n}\n\n//# sourceURL=webpack://dark-mode/./src/inject/dynamic-theme/variables.js?"); |
| 170 |
|
| 171 |
/***/ }), |
| 172 |
|
| 173 |
/***/ "./src/inject/dynamic-theme/watch.js": |
| 174 |
/*!*******************************************!*\ |
| 175 |
!*** ./src/inject/dynamic-theme/watch.js ***! |
| 176 |
\*******************************************/ |
| 177 |
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { |
| 178 |
|
| 179 |
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ stopWatchingForStyleChanges: () => (/* binding */ stopWatchingForStyleChanges)\n/* harmony export */ });\nconst observers = [];\nlet observedRoots;\nlet elementsDefinitionCallback;\nconst undefinedGroups = new Map();\nfunction resetObservers() {\n observers.forEach(o => o.disconnect());\n observers.splice(0, observers.length);\n observedRoots = new WeakSet();\n}\nfunction handleIsDefined(e) {\n canOptimizeUsingProxy = true;\n const tag = e.detail.tag;\n ASSERT(\"handleIsDefined() expects lower-case node names\", () => tag.toLowerCase() === tag);\n definedCustomElements.add(tag);\n if (resolvers.has(tag)) {\n const r = resolvers.get(tag);\n resolvers.delete(tag);\n r.forEach(r => r());\n }\n}\nfunction unsubscribeFromDefineCustomElements() {\n elementsDefinitionCallback = null;\n undefinedGroups.clear();\n document.removeEventListener(\"__adminify__isDefined\", handleIsDefined);\n}\nfunction stopWatchingForStyleChanges() {\n resetObservers();\n unsubscribeFromDefineCustomElements();\n}\n\n//# sourceURL=webpack://dark-mode/./src/inject/dynamic-theme/watch.js?"); |
| 180 |
|
| 181 |
/***/ }), |
| 182 |
|
| 183 |
/***/ "./src/inject/utils/dom.js": |
| 184 |
/*!*********************************!*\ |
| 185 |
!*** ./src/inject/utils/dom.js ***! |
| 186 |
\*********************************/ |
| 187 |
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { |
| 188 |
|
| 189 |
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ addReadyStateCompleteListener: () => (/* binding */ addReadyStateCompleteListener),\n/* harmony export */ cleanReadyStateCompleteListeners: () => (/* binding */ cleanReadyStateCompleteListeners),\n/* harmony export */ isDOMReady: () => (/* binding */ isDOMReady),\n/* harmony export */ isReadyStateComplete: () => (/* binding */ isReadyStateComplete),\n/* harmony export */ iterateShadowHosts: () => (/* binding */ iterateShadowHosts),\n/* harmony export */ removeDOMReadyListener: () => (/* binding */ removeDOMReadyListener),\n/* harmony export */ removeNode: () => (/* binding */ removeNode),\n/* harmony export */ watchForNodePosition: () => (/* binding */ watchForNodePosition)\n/* harmony export */ });\n/* harmony import */ var _utils_throttle__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../utils/throttle */ \"./src/utils/throttle.js\");\n/* harmony import */ var _utils_time__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../utils/time */ \"./src/utils/time.js\");\n\n\n// import { logWarn } from \"./log\";\n\n// **important**\nfunction watchForNodePosition(node, mode, onRestore = Function.prototype) {\n const MAX_ATTEMPTS_COUNT = 10;\n const RETRY_TIMEOUT = (0,_utils_time__WEBPACK_IMPORTED_MODULE_1__.getDuration)({\n seconds: 2\n });\n const ATTEMPTS_INTERVAL = (0,_utils_time__WEBPACK_IMPORTED_MODULE_1__.getDuration)({\n seconds: 10\n });\n const prevSibling = node.previousSibling;\n let parent = node.parentNode;\n if (!parent) {\n throw new Error(\"Unable to watch for node position: parent element not found\");\n }\n if (mode === \"prev-sibling\" && !prevSibling) {\n throw new Error(\"Unable to watch for node position: there is no previous sibling\");\n }\n let attempts = 0;\n let start = null;\n let timeoutId = null;\n const restore = (0,_utils_throttle__WEBPACK_IMPORTED_MODULE_0__.throttle)(() => {\n if (timeoutId) {\n return;\n }\n attempts++;\n const now = Date.now();\n if (start == null) {\n start = now;\n } else if (attempts >= MAX_ATTEMPTS_COUNT) {\n if (now - start < ATTEMPTS_INTERVAL) {\n // logWarn(\n // `Node position watcher paused: retry in ${RETRY_TIMEOUT}ms`,\n // node,\n // prevSibling\n // );\n timeoutId = setTimeout(() => {\n start = null;\n attempts = 0;\n timeoutId = null;\n restore();\n }, RETRY_TIMEOUT);\n return;\n }\n start = now;\n attempts = 1;\n }\n if (mode === \"head\") {\n if (prevSibling && prevSibling.parentNode !== parent) {\n // logWarn(\n // \"Unable to restore node position: sibling parent changed\",\n // node,\n // prevSibling,\n // parent\n // );\n stop();\n return;\n }\n }\n if (mode === \"prev-sibling\") {\n if (prevSibling.parentNode == null) {\n // logWarn(\n // \"Unable to restore node position: sibling was removed\",\n // node,\n // prevSibling,\n // parent\n // );\n stop();\n return;\n }\n if (prevSibling.parentNode !== parent) {\n // logWarn(\"Style was moved to another parent\", node, prevSibling, parent);\n updateParent(prevSibling.parentNode);\n }\n }\n\n // If parent becomes disconnected from the DOM, fetches the new head and\n // save that as parent. Do this only for the head mode, as those are\n // important nodes to keep.\n if (mode === \"head\" && !parent.isConnected) {\n parent = document.head;\n // TODO: Set correct prevSibling, which needs to be the last `.adminify` in <head> that isn't .darkeader--sync or .adminify--cors.\n }\n\n // logWarn(\"Restoring node position\", node, prevSibling, parent);\n parent.insertBefore(node, prevSibling && prevSibling.isConnected ? prevSibling.nextSibling : parent.firstChild);\n observer.takeRecords();\n onRestore && onRestore();\n });\n const observer = new MutationObserver(() => {\n if (mode === \"head\" && (node.parentNode !== parent || !node.parentNode.isConnected) || mode === \"prev-sibling\" && node.previousSibling !== prevSibling) {\n restore();\n }\n });\n const run = () => {\n // TODO: remove type cast after dependency update\n observer.observe(parent, {\n childList: true\n });\n };\n const stop = () => {\n // TODO: remove type cast after dependency update\n clearTimeout(timeoutId);\n observer.disconnect();\n restore.cancel();\n };\n const skip = () => {\n observer.takeRecords();\n };\n const updateParent = parentNode => {\n parent = parentNode;\n stop();\n run();\n };\n run();\n return {\n run,\n stop,\n skip\n };\n}\nfunction iterateShadowHosts(root, iterator) {\n if (root == null) {\n return;\n }\n const walker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT, {\n acceptNode(node) {\n return node.shadowRoot == null ? NodeFilter.FILTER_SKIP : NodeFilter.FILTER_ACCEPT;\n }\n });\n for (let node = root.shadowRoot ? walker.currentNode : walker.nextNode(); node != null; node = walker.nextNode()) {\n if (node.classList.contains(\"surfingkeys_hints_host\")) {\n continue;\n }\n iterator(node);\n iterateShadowHosts(node.shadowRoot, iterator);\n }\n}\nconst readyStateCompleteListeners = new Set();\n\n// `interactive` can and will be fired when their are still stylesheets loading.\n// We use certain actions that can cause a forced layout change, which is bad.\nfunction isReadyStateComplete() {\n return document.readyState === \"complete\";\n}\nfunction addReadyStateCompleteListener(listener) {\n isReadyStateComplete() ? listener() : readyStateCompleteListeners.add(listener);\n}\nlet isDOMReady = () => {\n return document.readyState === \"complete\" || document.readyState === \"interactive\";\n};\n\n//remove\n\nconst readyStateListeners = new Set();\nfunction removeNode(node) {\n node && node.parentNode && node.parentNode.removeChild(node);\n}\nfunction removeDOMReadyListener(listener) {\n readyStateListeners.delete(listener);\n}\nfunction cleanReadyStateCompleteListeners() {\n readyStateCompleteListeners.clear();\n}\n\n//# sourceURL=webpack://dark-mode/./src/inject/utils/dom.js?"); |
| 190 |
|
| 191 |
/***/ }), |
| 192 |
|
| 193 |
/***/ "./src/main.js": |
| 194 |
/*!*********************!*\ |
| 195 |
!*** ./src/main.js ***! |
| 196 |
\*********************/ |
| 197 |
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { |
| 198 |
|
| 199 |
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ remove: () => (/* binding */ remove),\n/* harmony export */ run: () => (/* binding */ run)\n/* harmony export */ });\n/* harmony import */ var _inject_dynamic_theme__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./inject/dynamic-theme */ \"./src/inject/dynamic-theme/index.js\");\n\nfunction run(config) {\n (0,_inject_dynamic_theme__WEBPACK_IMPORTED_MODULE_0__.run_createThemeAndWatchForUpdates)(config);\n}\nfunction remove() {\n (0,_inject_dynamic_theme__WEBPACK_IMPORTED_MODULE_0__.removeDynamicTheme)();\n}\n\n//# sourceURL=webpack://dark-mode/./src/main.js?"); |
| 200 |
|
| 201 |
/***/ }), |
| 202 |
|
| 203 |
/***/ "./src/utils/array.js": |
| 204 |
/*!****************************!*\ |
| 205 |
!*** ./src/utils/array.js ***! |
| 206 |
\****************************/ |
| 207 |
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { |
| 208 |
|
| 209 |
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ forEach: () => (/* binding */ forEach),\n/* harmony export */ push: () => (/* binding */ push),\n/* harmony export */ toArray: () => (/* binding */ toArray)\n/* harmony export */ });\nfunction isArrayLike(items) {\n return items.length != null;\n}\n\n// NOTE: Iterating Array-like items using `for .. of` is 3x slower in Firefox\n// https://jsben.ch/kidOp\nfunction forEach(items, iterator) {\n if (isArrayLike(items)) {\n for (let i = 0, len = items.length; i < len; i++) {\n iterator(items[i]);\n }\n } else {\n for (const item of items) {\n iterator(item);\n }\n }\n}\n\n// NOTE: Pushing items like `arr.push(...items)` is 3x slower in Firefox\n// https://jsben.ch/nr9OF\nfunction push(array, addition) {\n forEach(addition, a => array.push(a));\n}\n\n// NOTE: Using `Array.from()` is 2x (FF) — 5x (Chrome) slower for ArrayLike (not for Iterable)\n// https://jsben.ch/FJ1mO\n// https://jsben.ch/ZmViL\nfunction toArray(items) {\n const results = [];\n for (let i = 0, len = items.length; i < len; i++) {\n results.push(items[i]);\n }\n return results;\n}\n\n//# sourceURL=webpack://dark-mode/./src/utils/array.js?"); |
| 210 |
|
| 211 |
/***/ }), |
| 212 |
|
| 213 |
/***/ "./src/utils/async-queue.js": |
| 214 |
/*!**********************************!*\ |
| 215 |
!*** ./src/utils/async-queue.js ***! |
| 216 |
\**********************************/ |
| 217 |
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { |
| 218 |
|
| 219 |
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (/* binding */ AsyncQueue)\n/* harmony export */ });\n// AsyncQueue is a class that helps with managing tasks.\n// More specifically, it helps with tasks that are often used.\n// It's fully asyncronous and uses promises and tries to get 60FPS.\nclass AsyncQueue {\n queue = [];\n timerId = null;\n frameDuration = 1000 / 60;\n addToQueue(entry) {\n this.queue.push(entry);\n this.startQueue();\n }\n stopQueue() {\n if (this.timerId !== null) {\n cancelAnimationFrame(this.timerId);\n this.timerId = null;\n }\n this.queue = [];\n }\n\n // Ensures 60FPS.\n startQueue() {\n if (this.timerId) {\n return;\n }\n this.timerId = requestAnimationFrame(() => {\n this.timerId = null;\n const start = Date.now();\n let cb;\n while (cb = this.queue.shift()) {\n cb();\n if (Date.now() - start >= this.frameDuration) {\n this.startQueue();\n break;\n }\n }\n });\n }\n}\n\n//# sourceURL=webpack://dark-mode/./src/utils/async-queue.js?"); |
| 220 |
|
| 221 |
/***/ }), |
| 222 |
|
| 223 |
/***/ "./src/utils/color.js": |
| 224 |
/*!****************************!*\ |
| 225 |
!*** ./src/utils/color.js ***! |
| 226 |
\****************************/ |
| 227 |
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { |
| 228 |
|
| 229 |
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ clearColorCache: () => (/* binding */ clearColorCache),\n/* harmony export */ getSRGBLightness: () => (/* binding */ getSRGBLightness),\n/* harmony export */ hslToRGB: () => (/* binding */ hslToRGB),\n/* harmony export */ hslToString: () => (/* binding */ hslToString),\n/* harmony export */ lowerCalcExpression: () => (/* binding */ lowerCalcExpression),\n/* harmony export */ parse: () => (/* binding */ parse),\n/* harmony export */ parseColorWithCache: () => (/* binding */ parseColorWithCache),\n/* harmony export */ parseToHSLWithCache: () => (/* binding */ parseToHSLWithCache),\n/* harmony export */ rgbToHSL: () => (/* binding */ rgbToHSL),\n/* harmony export */ rgbToHexString: () => (/* binding */ rgbToHexString),\n/* harmony export */ rgbToString: () => (/* binding */ rgbToString)\n/* harmony export */ });\n/* harmony import */ var _math_eval__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./math-eval */ \"./src/utils/math-eval.js\");\n/* harmony import */ var _text__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./text */ \"./src/utils/text.js\");\n\n\nconst hslaParseCache = new Map();\nconst rgbaParseCache = new Map();\nfunction parseColorWithCache($color) {\n $color = $color.trim();\n if (rgbaParseCache.has($color)) {\n return rgbaParseCache.get($color);\n }\n // We cannot _really_ parse any color which has the calc() expression,\n // so we try our best to remove those and then parse the value.\n if ($color.includes(\"calc(\")) {\n $color = lowerCalcExpression($color);\n }\n const color = parse($color);\n color && rgbaParseCache.set($color, color);\n return color;\n}\nfunction parseToHSLWithCache(color) {\n if (hslaParseCache.has(color)) {\n return hslaParseCache.get(color);\n }\n const rgb = parseColorWithCache(color);\n if (!rgb) {\n return null;\n }\n const hsl = rgbToHSL(rgb);\n hslaParseCache.set(color, hsl);\n return hsl;\n}\nfunction clearColorCache() {\n hslaParseCache.clear();\n rgbaParseCache.clear();\n}\n\n// https://en.wikipedia.org/wiki/HSL_and_HSV\nfunction hslToRGB({\n h,\n s,\n l,\n a = 1\n}) {\n if (s === 0) {\n const [r, b, g] = [l, l, l].map(x => Math.round(x * 255));\n return {\n r,\n g,\n b,\n a\n };\n }\n const c = (1 - Math.abs(2 * l - 1)) * s;\n const x = c * (1 - Math.abs(h / 60 % 2 - 1));\n const m = l - c / 2;\n const [r, g, b] = (h < 60 ? [c, x, 0] : h < 120 ? [x, c, 0] : h < 180 ? [0, c, x] : h < 240 ? [0, x, c] : h < 300 ? [x, 0, c] : [c, 0, x]).map(n => Math.round((n + m) * 255));\n return {\n r,\n g,\n b,\n a\n };\n}\n\n// https://en.wikipedia.org/wiki/HSL_and_HSV\nfunction rgbToHSL({\n r: r255,\n g: g255,\n b: b255,\n a = 1\n}) {\n const r = r255 / 255;\n const g = g255 / 255;\n const b = b255 / 255;\n const max = Math.max(r, g, b);\n const min = Math.min(r, g, b);\n const c = max - min;\n const l = (max + min) / 2;\n if (c === 0) {\n return {\n h: 0,\n s: 0,\n l,\n a\n };\n }\n let h = (max === r ? (g - b) / c % 6 : max === g ? (b - r) / c + 2 : (r - g) / c + 4) * 60;\n if (h < 0) {\n h += 360;\n }\n const s = c / (1 - Math.abs(2 * l - 1));\n return {\n h,\n s,\n l,\n a\n };\n}\nfunction toFixed(n, digits = 0) {\n const fixed = n.toFixed(digits);\n if (digits === 0) {\n return fixed;\n }\n const dot = fixed.indexOf(\".\");\n if (dot >= 0) {\n const zerosMatch = fixed.match(/0+$/);\n if (zerosMatch) {\n if (zerosMatch.index === dot + 1) {\n return fixed.substring(0, dot);\n }\n return fixed.substring(0, zerosMatch.index);\n }\n }\n return fixed;\n}\nfunction rgbToString(rgb) {\n const {\n r,\n g,\n b,\n a\n } = rgb;\n if (a != null && a < 1) {\n return `rgba(${toFixed(r)}, ${toFixed(g)}, ${toFixed(b)}, ${toFixed(a, 2)})`;\n }\n return `rgb(${toFixed(r)}, ${toFixed(g)}, ${toFixed(b)})`;\n}\nfunction rgbToHexString({\n r,\n g,\n b,\n a\n}) {\n return `#${(a != null && a < 1 ? [r, g, b, Math.round(a * 255)] : [r, g, b]).map(x => {\n return `${x < 16 ? \"0\" : \"\"}${x.toString(16)}`;\n }).join(\"\")}`;\n}\nfunction hslToString(hsl) {\n const {\n h,\n s,\n l,\n a\n } = hsl;\n if (a != null && a < 1) {\n return `hsla(${toFixed(h)}, ${toFixed(s * 100)}%, ${toFixed(l * 100)}%, ${toFixed(a, 2)})`;\n }\n return `hsl(${toFixed(h)}, ${toFixed(s * 100)}%, ${toFixed(l * 100)}%)`;\n}\nconst rgbMatch = /^rgba?\\([^\\(\\)]+\\)$/;\nconst hslMatch = /^hsla?\\([^\\(\\)]+\\)$/;\nconst hexMatch = /^#[0-9a-f]+$/i;\nfunction parse($color) {\n const c = $color.trim().toLowerCase();\n if (c.match(rgbMatch)) {\n return parseRGB(c);\n }\n if (c.match(hslMatch)) {\n return parseHSL(c);\n }\n if (c.match(hexMatch)) {\n return parseHex(c);\n }\n if (knownColors.has(c)) {\n return getColorByName(c);\n }\n if (systemColors.has(c)) {\n return getSystemColor(c);\n }\n if ($color === \"transparent\") {\n return {\n r: 0,\n g: 0,\n b: 0,\n a: 0\n };\n }\n return null;\n}\nfunction getNumbers($color) {\n const numbers = [];\n let prevPos = 0;\n let isMining = false;\n // Get the first `(`.\n const startIndex = $color.indexOf(\"(\");\n $color = $color.substring(startIndex + 1, $color.length - 1);\n for (let i = 0; i < $color.length; i++) {\n const c = $color[i];\n // Check if `c` is a digit.\n if (c >= \"0\" && c <= \"9\" || c === \".\" || c === \"+\" || c === \"-\") {\n // Enable the mining flag.\n isMining = true;\n } else if (isMining && (c === \" \" || c === \",\" || c === \"/\")) {\n // isMining is true and we got a terminating\n // character. So we can push the current number\n // into the array.\n numbers.push($color.substring(prevPos, i));\n // Disable the mining flag.\n isMining = false;\n // Ensure the prevPos is correct.\n prevPos = i + 1;\n } else if (!isMining) {\n // Ensure the prevPos is correct.\n prevPos = i + 1;\n }\n }\n // Push the last number.\n if (isMining) {\n numbers.push($color.substring(prevPos, $color.length));\n }\n return numbers;\n}\nfunction getNumbersFromString(str, range, units) {\n const raw = getNumbers(str);\n const unitsList = Object.entries(units);\n const numbers = raw.map(r => r.trim()).map((r, i) => {\n let n;\n const unit = unitsList.find(([u]) => r.endsWith(u));\n if (unit) {\n n = parseFloat(r.substring(0, r.length - unit[0].length)) / unit[1] * range[i];\n } else {\n n = parseFloat(r);\n }\n if (range[i] > 1) {\n return Math.round(n);\n }\n return n;\n });\n return numbers;\n}\nconst rgbRange = [255, 255, 255, 1];\nconst rgbUnits = {\n \"%\": 100\n};\nfunction parseRGB($rgb) {\n const [r, g, b, a = 1] = getNumbersFromString($rgb, rgbRange, rgbUnits);\n return {\n r,\n g,\n b,\n a\n };\n}\nconst hslRange = [360, 1, 1, 1];\nconst hslUnits = {\n \"%\": 100,\n deg: 360,\n rad: 2 * Math.PI,\n turn: 1\n};\nfunction parseHSL($hsl) {\n const [h, s, l, a = 1] = getNumbersFromString($hsl, hslRange, hslUnits);\n return hslToRGB({\n h,\n s,\n l,\n a\n });\n}\nfunction parseHex($hex) {\n const h = $hex.substring(1);\n switch (h.length) {\n case 3:\n case 4:\n {\n const [r, g, b] = [0, 1, 2].map(i => parseInt(`${h[i]}${h[i]}`, 16));\n const a = h.length === 3 ? 1 : parseInt(`${h[3]}${h[3]}`, 16) / 255;\n return {\n r,\n g,\n b,\n a\n };\n }\n case 6:\n case 8:\n {\n const [r, g, b] = [0, 2, 4].map(i => parseInt(h.substring(i, i + 2), 16));\n const a = h.length === 6 ? 1 : parseInt(h.substring(6, 8), 16) / 255;\n return {\n r,\n g,\n b,\n a\n };\n }\n }\n return null;\n}\nfunction getColorByName($color) {\n const n = knownColors.get($color);\n return {\n r: n >> 16 & 255,\n g: n >> 8 & 255,\n b: n >> 0 & 255,\n a: 1\n };\n}\nfunction getSystemColor($color) {\n const n = systemColors.get($color);\n return {\n r: n >> 16 & 255,\n g: n >> 8 & 255,\n b: n >> 0 & 255,\n a: 1\n };\n}\n\n// lowerCalcExpression is a helper function that tries to remove `calc(...)`\n// expressions from the given string. It can only lower expressions to a certain\n// degree so we can keep this function easy and simple to understand.\nfunction lowerCalcExpression(color) {\n // searchIndex will be used as searchIndex and as a \"cursor\" within\n // the calc(...) expression.\n let searchIndex = 0;\n\n // Replace the content between two indices.\n const replaceBetweenIndices = (start, end, replacement) => {\n color = color.substring(0, start) + replacement + color.substring(end);\n };\n\n // Run this code until it doesn't find any `calc(...)`.\n while ((searchIndex = color.indexOf(\"calc(\")) !== -1) {\n // Get the parentheses ranges of `calc(...)`.\n const range = (0,_text__WEBPACK_IMPORTED_MODULE_1__.getParenthesesRange)(color, searchIndex);\n if (!range) {\n break;\n }\n\n // Get the content between the parentheses.\n let slice = color.slice(range.start + 1, range.end - 1);\n // Does the content include a percentage?\n const includesPercentage = slice.includes(\"%\");\n // Remove all percentages.\n slice = slice.split(\"%\").join(\"\");\n\n // Pass the content to the evalMath library and round its output.\n const output = Math.round((0,_math_eval__WEBPACK_IMPORTED_MODULE_0__.evalMath)(slice));\n\n // Replace `calc(...)` with the result.\n replaceBetweenIndices(range.start - 4, range.end, output + (includesPercentage ? \"%\" : \"\"));\n }\n return color;\n}\nconst knownColors = new Map(Object.entries({\n aliceblue: 0xf0f8ff,\n antiquewhite: 0xfaebd7,\n aqua: 0x00ffff,\n aquamarine: 0x7fffd4,\n azure: 0xf0ffff,\n beige: 0xf5f5dc,\n bisque: 0xffe4c4,\n black: 0x000000,\n blanchedalmond: 0xffebcd,\n blue: 0x0000ff,\n blueviolet: 0x8a2be2,\n brown: 0xa52a2a,\n burlywood: 0xdeb887,\n cadetblue: 0x5f9ea0,\n chartreuse: 0x7fff00,\n chocolate: 0xd2691e,\n coral: 0xff7f50,\n cornflowerblue: 0x6495ed,\n cornsilk: 0xfff8dc,\n crimson: 0xdc143c,\n cyan: 0x00ffff,\n darkblue: 0x00008b,\n darkcyan: 0x008b8b,\n darkgoldenrod: 0xb8860b,\n darkgray: 0xa9a9a9,\n darkgrey: 0xa9a9a9,\n darkgreen: 0x006400,\n darkkhaki: 0xbdb76b,\n darkmagenta: 0x8b008b,\n darkolivegreen: 0x556b2f,\n darkorange: 0xff8c00,\n darkorchid: 0x9932cc,\n darkred: 0x8b0000,\n darksalmon: 0xe9967a,\n darkseagreen: 0x8fbc8f,\n darkslateblue: 0x483d8b,\n darkslategray: 0x2f4f4f,\n darkslategrey: 0x2f4f4f,\n darkturquoise: 0x00ced1,\n darkviolet: 0x9400d3,\n deeppink: 0xff1493,\n deepskyblue: 0x00bfff,\n dimgray: 0x696969,\n dimgrey: 0x696969,\n dodgerblue: 0x1e90ff,\n firebrick: 0xb22222,\n floralwhite: 0xfffaf0,\n forestgreen: 0x228b22,\n fuchsia: 0xff00ff,\n gainsboro: 0xdcdcdc,\n ghostwhite: 0xf8f8ff,\n gold: 0xffd700,\n goldenrod: 0xdaa520,\n gray: 0x808080,\n grey: 0x808080,\n green: 0x008000,\n greenyellow: 0xadff2f,\n honeydew: 0xf0fff0,\n hotpink: 0xff69b4,\n indianred: 0xcd5c5c,\n indigo: 0x4b0082,\n ivory: 0xfffff0,\n khaki: 0xf0e68c,\n lavender: 0xe6e6fa,\n lavenderblush: 0xfff0f5,\n lawngreen: 0x7cfc00,\n lemonchiffon: 0xfffacd,\n lightblue: 0xadd8e6,\n lightcoral: 0xf08080,\n lightcyan: 0xe0ffff,\n lightgoldenrodyellow: 0xfafad2,\n lightgray: 0xd3d3d3,\n lightgrey: 0xd3d3d3,\n lightgreen: 0x90ee90,\n lightpink: 0xffb6c1,\n lightsalmon: 0xffa07a,\n lightseagreen: 0x20b2aa,\n lightskyblue: 0x87cefa,\n lightslategray: 0x778899,\n lightslategrey: 0x778899,\n lightsteelblue: 0xb0c4de,\n lightyellow: 0xffffe0,\n lime: 0x00ff00,\n limegreen: 0x32cd32,\n linen: 0xfaf0e6,\n magenta: 0xff00ff,\n maroon: 0x800000,\n mediumaquamarine: 0x66cdaa,\n mediumblue: 0x0000cd,\n mediumorchid: 0xba55d3,\n mediumpurple: 0x9370db,\n mediumseagreen: 0x3cb371,\n mediumslateblue: 0x7b68ee,\n mediumspringgreen: 0x00fa9a,\n mediumturquoise: 0x48d1cc,\n mediumvioletred: 0xc71585,\n midnightblue: 0x191970,\n mintcream: 0xf5fffa,\n mistyrose: 0xffe4e1,\n moccasin: 0xffe4b5,\n navajowhite: 0xffdead,\n navy: 0x000080,\n oldlace: 0xfdf5e6,\n olive: 0x808000,\n olivedrab: 0x6b8e23,\n orange: 0xffa500,\n orangered: 0xff4500,\n orchid: 0xda70d6,\n palegoldenrod: 0xeee8aa,\n palegreen: 0x98fb98,\n paleturquoise: 0xafeeee,\n palevioletred: 0xdb7093,\n papayawhip: 0xffefd5,\n peachpuff: 0xffdab9,\n peru: 0xcd853f,\n pink: 0xffc0cb,\n plum: 0xdda0dd,\n powderblue: 0xb0e0e6,\n purple: 0x800080,\n rebeccapurple: 0x663399,\n red: 0xff0000,\n rosybrown: 0xbc8f8f,\n royalblue: 0x4169e1,\n saddlebrown: 0x8b4513,\n salmon: 0xfa8072,\n sandybrown: 0xf4a460,\n seagreen: 0x2e8b57,\n seashell: 0xfff5ee,\n sienna: 0xa0522d,\n silver: 0xc0c0c0,\n skyblue: 0x87ceeb,\n slateblue: 0x6a5acd,\n slategray: 0x708090,\n slategrey: 0x708090,\n snow: 0xfffafa,\n springgreen: 0x00ff7f,\n steelblue: 0x4682b4,\n tan: 0xd2b48c,\n teal: 0x008080,\n thistle: 0xd8bfd8,\n tomato: 0xff6347,\n turquoise: 0x40e0d0,\n violet: 0xee82ee,\n wheat: 0xf5deb3,\n white: 0xffffff,\n whitesmoke: 0xf5f5f5,\n yellow: 0xffff00,\n yellowgreen: 0x9acd32\n}));\nconst systemColors = new Map(Object.entries({\n ActiveBorder: 0x3b99fc,\n ActiveCaption: 0x000000,\n AppWorkspace: 0xaaaaaa,\n Background: 0x6363ce,\n ButtonFace: 0xffffff,\n ButtonHighlight: 0xe9e9e9,\n ButtonShadow: 0x9fa09f,\n ButtonText: 0x000000,\n CaptionText: 0x000000,\n GrayText: 0x7f7f7f,\n Highlight: 0xb2d7ff,\n HighlightText: 0x000000,\n InactiveBorder: 0xffffff,\n InactiveCaption: 0xffffff,\n InactiveCaptionText: 0x000000,\n InfoBackground: 0xfbfcc5,\n InfoText: 0x000000,\n Menu: 0xf6f6f6,\n MenuText: 0xffffff,\n Scrollbar: 0xaaaaaa,\n ThreeDDarkShadow: 0x000000,\n ThreeDFace: 0xc0c0c0,\n ThreeDHighlight: 0xffffff,\n ThreeDLightShadow: 0xffffff,\n ThreeDShadow: 0x000000,\n Window: 0xececec,\n WindowFrame: 0xaaaaaa,\n WindowText: 0x000000,\n \"-webkit-focus-ring-color\": 0xe59700\n}).map(([key, value]) => [key.toLowerCase(), value]));\n\n// https://en.wikipedia.org/wiki/Relative_luminance\nfunction getSRGBLightness(r, g, b) {\n return (0.2126 * r + 0.7152 * g + 0.0722 * b) / 255;\n}\n\n//# sourceURL=webpack://dark-mode/./src/utils/color.js?"); |
| 230 |
|
| 231 |
/***/ }), |
| 232 |
|
| 233 |
/***/ "./src/utils/ipv6.js": |
| 234 |
/*!***************************!*\ |
| 235 |
!*** ./src/utils/ipv6.js ***! |
| 236 |
\***************************/ |
| 237 |
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { |
| 238 |
|
| 239 |
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ compareIPV6: () => (/* binding */ compareIPV6),\n/* harmony export */ isIPV6: () => (/* binding */ isIPV6)\n/* harmony export */ });\nconst simpleIPV6Regex = /\\[[0-9:a-zA-Z]+?\\]/;\nfunction isIPV6(url) {\n const openingBracketIndex = simpleIPV6Regex.exec(url);\n if (!openingBracketIndex) {\n return false;\n }\n const queryIndex = url.indexOf(\"?\");\n if (queryIndex >= 0 && openingBracketIndex.index > queryIndex) {\n return false;\n }\n return true;\n}\nconst ipV6HostRegex = /\\[.*?\\](\\:\\d+)?/;\nfunction compareIPV6(firstURL, secondURL) {\n const firstHost = firstURL.match(ipV6HostRegex)[0];\n const secondHost = secondURL.match(ipV6HostRegex)[0];\n return firstHost === secondHost;\n}\n\n//# sourceURL=webpack://dark-mode/./src/utils/ipv6.js?"); |
| 240 |
|
| 241 |
/***/ }), |
| 242 |
|
| 243 |
/***/ "./src/utils/math-eval.js": |
| 244 |
/*!********************************!*\ |
| 245 |
!*** ./src/utils/math-eval.js ***! |
| 246 |
\********************************/ |
| 247 |
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { |
| 248 |
|
| 249 |
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ evalMath: () => (/* binding */ evalMath)\n/* harmony export */ });\n// evalMath is a function that's able to evaluates a mathematical expression and return it's ouput.\n//\n// Internally it uses the Shunting Yard algoritm. First it produces a reverse polish notation(RPN) stack.\n// Example: 1 + 2 * 3 -> [1, 2, 3, *, +] which with parentheses means 1 (2 3 *) +\n//\n// Then it evaluates the RPN stack and returns the output.\nfunction evalMath(expression) {\n // Stack where operators & numbers are stored in RPN.\n const rpnStack = [];\n // The working stack where new tokens are pushed.\n const workingStack = [];\n let lastToken;\n // Iterate over the expression.\n for (let i = 0, len = expression.length; i < len; i++) {\n const token = expression[i];\n\n // Skip if the token is empty or a whitespace.\n if (!token || token === \" \") {\n continue;\n }\n\n // Is the token a operator?\n if (operators.has(token)) {\n const op = operators.get(token);\n\n // Go trough the workingstack and determine it's place in the workingStack\n while (workingStack.length) {\n const currentOp = operators.get(workingStack[0]);\n if (!currentOp) {\n break;\n }\n\n // Is the current operation equal or less than the current operation?\n // Then move that operation to the rpnStack.\n if (op.lessOrEqualThan(currentOp)) {\n rpnStack.push(workingStack.shift());\n } else {\n break;\n }\n }\n // Add the operation to the workingStack.\n workingStack.unshift(token);\n // Otherwise was the last token a operator?\n } else if (!lastToken || operators.has(lastToken)) {\n rpnStack.push(token);\n // Otherwise just append the result to the last token(e.g. multiple digits numbers).\n } else {\n rpnStack[rpnStack.length - 1] += token;\n }\n // Set the last token.\n lastToken = token;\n }\n\n // Push the working stack on top of the rpnStack.\n rpnStack.push(...workingStack);\n\n // Now evaluate the rpnStack.\n const stack = [];\n for (let i = 0, len = rpnStack.length; i < len; i++) {\n const op = operators.get(rpnStack[i]);\n if (op) {\n // Get the arguments of for the operation(first two in the stack).\n const args = stack.splice(0, 2);\n // Excute it, because of reverse notation we first pass second item then the first item.\n stack.push(op.exec(args[1], args[0]));\n } else {\n // Add the number to the stack.\n stack.unshift(parseFloat(rpnStack[i]));\n }\n }\n return stack[0];\n}\n\n// Operator class defines a operator that can be parsed & evaluated by evalMath.\nclass Operator {\n constructor(precedence, method) {\n this.precendce = precedence;\n this.execMethod = method;\n }\n exec(left, right) {\n return this.execMethod(left, right);\n }\n lessOrEqualThan(op) {\n return this.precendce <= op.precendce;\n }\n}\nconst operators = new Map([[\"+\", new Operator(1, (left, right) => left + right)], [\"-\", new Operator(1, (left, right) => left - right)], [\"*\", new Operator(2, (left, right) => left * right)], [\"/\", new Operator(2, (left, right) => left / right)]]);\n\n//# sourceURL=webpack://dark-mode/./src/utils/math-eval.js?"); |
| 250 |
|
| 251 |
/***/ }), |
| 252 |
|
| 253 |
/***/ "./src/utils/math.js": |
| 254 |
/*!***************************!*\ |
| 255 |
!*** ./src/utils/math.js ***! |
| 256 |
\***************************/ |
| 257 |
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { |
| 258 |
|
| 259 |
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ clamp: () => (/* binding */ clamp),\n/* harmony export */ multiplyMatrices: () => (/* binding */ multiplyMatrices),\n/* harmony export */ scale: () => (/* binding */ scale)\n/* harmony export */ });\nfunction scale(x, inLow, inHigh, outLow, outHigh) {\n return (x - inLow) * (outHigh - outLow) / (inHigh - inLow) + outLow;\n}\nfunction clamp(x, min, max) {\n return Math.min(max, Math.max(min, x));\n}\n\n// Note: the caller is responsible for ensuring that matrix dimensions make sense\nfunction multiplyMatrices(m1, m2) {\n const result = [];\n for (let i = 0, len = m1.length; i < len; i++) {\n result[i] = [];\n for (let j = 0, len2 = m2[0].length; j < len2; j++) {\n let sum = 0;\n for (let k = 0, len3 = m1[0].length; k < len3; k++) {\n sum += m1[i][k] * m2[k][j];\n }\n result[i][j] = sum;\n }\n }\n return result;\n}\n\n//# sourceURL=webpack://dark-mode/./src/utils/math.js?"); |
| 260 |
|
| 261 |
/***/ }), |
| 262 |
|
| 263 |
/***/ "./src/utils/network.js": |
| 264 |
/*!******************************!*\ |
| 265 |
!*** ./src/utils/network.js ***! |
| 266 |
\******************************/ |
| 267 |
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { |
| 268 |
|
| 269 |
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ loadAsDataURL: () => (/* binding */ loadAsDataURL),\n/* harmony export */ readResponseAsDataURL: () => (/* binding */ readResponseAsDataURL)\n/* harmony export */ });\n/* harmony import */ var _platform__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./platform */ \"./src/utils/platform.js\");\n\nasync function getOKResponse(url, mimeType, origin) {\n const response = await fetch(url, {\n cache: \"force-cache\",\n credentials: \"omit\",\n referrer: origin\n });\n\n // Firefox bug, content type is \"application/x-unknown-content-type\"\n if (_platform__WEBPACK_IMPORTED_MODULE_0__.isFirefox && mimeType === \"text/css\" && url.startsWith(\"moz-extension://\") && url.endsWith(\".css\")) {\n return response;\n }\n if (mimeType && !response.headers.get(\"Content-Type\").startsWith(mimeType)) {\n throw new Error(`Mime type mismatch when loading ${url}`);\n }\n if (!response.ok) {\n throw new Error(`Unable to load ${url} ${response.status} ${response.statusText}`);\n }\n return response;\n}\nasync function loadAsDataURL(url, mimeType) {\n const response = await getOKResponse(url, mimeType);\n return await readResponseAsDataURL(response);\n}\nasync function readResponseAsDataURL(response) {\n const blob = await response.blob();\n const dataURL = await new Promise(resolve => {\n const reader = new FileReader();\n reader.onloadend = () => resolve(reader.result);\n reader.readAsDataURL(blob);\n });\n return dataURL;\n}\n\n// export async function loadAsText(url, mimeType, origin) {\n// const response = await getOKResponse(url, mimeType, origin);\n// return await response.text();\n// }\n\n//# sourceURL=webpack://dark-mode/./src/utils/network.js?"); |
| 270 |
|
| 271 |
/***/ }), |
| 272 |
|
| 273 |
/***/ "./src/utils/parsing.js": |
| 274 |
/*!******************************!*\ |
| 275 |
!*** ./src/utils/parsing.js ***! |
| 276 |
\******************************/ |
| 277 |
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { |
| 278 |
|
| 279 |
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ parseGradient: () => (/* binding */ parseGradient)\n/* harmony export */ });\n/* harmony import */ var _text__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./text */ \"./src/utils/text.js\");\n\nconst gradientLength = \"gradient\".length;\nconst conicGradient = \"conic-\";\nconst conicGradientLength = conicGradient.length;\nconst radialGradient = \"radial-\";\nconst linearGradient = \"linear-\";\n\n// Parse the value according to the specifiction.\n//\n// Specification: https://drafts.csswg.org/css-images-4/#gradients\nfunction parseGradient(value) {\n const result = [];\n\n // Loop trough the value until we find the first `gradient` keyword.\n // We will be using the indexOf to find the keyword. From their on\n // we will check which specific graidient we are dealing with.\n // Then we will try to parse the rest of the value as a gradient.\n let index = 0;\n let startIndex = conicGradient.length;\n while ((index = value.indexOf(\"gradient\", startIndex)) !== -1) {\n let typeGradient;\n // Now we check the type of gradient.\n // the current index starts at `g` of gradient.\n // So we have to do a reverse lookup to find the type of gradient.\n // Because each type of gradient has a different length\n // will we get the substring of the possible gradient types.\n [linearGradient, radialGradient, conicGradient].find(possibleType => {\n if (index - possibleType.length >= 0) {\n const possibleGradient = value.substring(index - possibleType.length, index);\n if (possibleGradient === possibleType) {\n // Check if the type has a `-` before the `type-gradient` keyword.\n // If it does, it's a repeating gradient.\n if (value.slice(index - possibleType.length - 10, index - possibleType.length - 1) === \"repeating\") {\n typeGradient = `repeating-${possibleType}gradient`;\n return true;\n }\n if (value.slice(index - possibleType.length - 8, index - possibleType.length - 1) === \"-webkit\") {\n typeGradient = `-webkit-${possibleType}gradient`;\n return true;\n }\n typeGradient = `${possibleType}gradient`;\n return true;\n }\n }\n });\n if (!typeGradient) {\n break;\n }\n\n // Now we know the type of gradient.\n // We can go parse the rest of the value as a gradient.\n const {\n start,\n end\n } = (0,_text__WEBPACK_IMPORTED_MODULE_0__.getParenthesesRange)(value, index + gradientLength);\n const match = value.substring(start + 1, end - 1);\n startIndex = end + 1 + conicGradientLength;\n result.push({\n typeGradient,\n match,\n // <type>-gradient() is not within match, so in order to still \"skip\" that section\n // we add that length as offset.\n offset: typeGradient.length + 2,\n index: index - typeGradient.length + gradientLength,\n hasComma: true\n });\n }\n\n // Set the last result to not have a comma.\n if (result.length) {\n result[result.length - 1].hasComma = false;\n }\n return result;\n}\n\n//# sourceURL=webpack://dark-mode/./src/utils/parsing.js?"); |
| 280 |
|
| 281 |
/***/ }), |
| 282 |
|
| 283 |
/***/ "./src/utils/platform.js": |
| 284 |
/*!*******************************!*\ |
| 285 |
!*** ./src/utils/platform.js ***! |
| 286 |
\*******************************/ |
| 287 |
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { |
| 288 |
|
| 289 |
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ chromiumVersion: () => (/* binding */ chromiumVersion),\n/* harmony export */ compareChromeVersions: () => (/* binding */ compareChromeVersions),\n/* harmony export */ firefoxVersion: () => (/* binding */ firefoxVersion),\n/* harmony export */ isCSSColorSchemePropSupported: () => (/* binding */ isCSSColorSchemePropSupported),\n/* harmony export */ isFirefox: () => (/* binding */ isFirefox),\n/* harmony export */ isSafari: () => (/* binding */ isSafari),\n/* harmony export */ isShadowDomSupported: () => (/* binding */ isShadowDomSupported)\n/* harmony export */ });\nconst isShadowDomSupported = typeof ShadowRoot === \"function\";\nconst isFirefox = navigator.userAgent.indexOf(\"Firefox\") != -1;\nconst isSafari = navigator.userAgent.indexOf(\"Safari\") != -1;\nconst isCSSColorSchemePropSupported = (() => {\n try {\n if (typeof document === \"undefined\") {\n return false;\n }\n const el = document.createElement(\"div\");\n if (!el || typeof el.style !== \"object\") {\n return false;\n }\n if (typeof el.style.colorScheme === \"string\") {\n return true;\n }\n // TODO: remove the following code after enforcing strong CSP in all builds\n // This feature detection method requires weak or missing CSP in manifest.json\n el.setAttribute(\"style\", \"color-scheme: dark\");\n return el.style.colorScheme === \"dark\";\n } catch (e) {\n return false;\n }\n})();\nfunction compareChromeVersions($a, $b) {\n const a = $a.split(\".\").map(x => parseInt(x));\n const b = $b.split(\".\").map(x => parseInt(x));\n for (let i = 0; i < a.length; i++) {\n if (a[i] !== b[i]) {\n return a[i] < b[i] ? -1 : 1;\n }\n }\n return 0;\n}\nconst chromiumVersion = (() => {\n const m = navigator.userAgent.match(/chrom(?:e|ium)(?:\\/| )([^ ]+)/);\n if (m && m[1]) {\n return m[1];\n }\n return \"\";\n})();\nconst firefoxVersion = (() => {\n const m = navigator.userAgent.match(/(?:firefox|librewolf)(?:\\/| )([^ ]+)/);\n if (m && m[1]) {\n return m[1];\n }\n return \"\";\n})();\n\n//# sourceURL=webpack://dark-mode/./src/utils/platform.js?"); |
| 290 |
|
| 291 |
/***/ }), |
| 292 |
|
| 293 |
/***/ "./src/utils/text.js": |
| 294 |
/*!***************************!*\ |
| 295 |
!*** ./src/utils/text.js ***! |
| 296 |
\***************************/ |
| 297 |
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { |
| 298 |
|
| 299 |
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ formatArray: () => (/* binding */ formatArray),\n/* harmony export */ formatCSS: () => (/* binding */ formatCSS),\n/* harmony export */ getMatches: () => (/* binding */ getMatches),\n/* harmony export */ getParenthesesRange: () => (/* binding */ getParenthesesRange),\n/* harmony export */ parseArray: () => (/* binding */ parseArray)\n/* harmony export */ });\n// export function getTextPositionMessage(text, index) {\n// if (!isFinite(index)) {\n// throw new Error(`Wrong char index ${index}`);\n// }\n// let message = \"\";\n// let line = 0;\n// let prevLn;\n// let nextLn = 0;\n// do {\n// line++;\n// prevLn = nextLn;\n// nextLn = text.indexOf(\"\\n\", prevLn + 1);\n// } while (nextLn >= 0 && nextLn <= index);\n// const column = index - prevLn;\n// message += `line ${line}, column ${column}`;\n// message += \"\\n\";\n// if (index < text.length) {\n// message += text.substring(prevLn + 1, nextLn);\n// } else {\n// message += text.substring(text.lastIndexOf(\"\\n\") + 1);\n// }\n// message += \"\\n\";\n// message += `${new Array(column).join(\"-\")}^`;\n// return message;\n// }\n\n// export function getTextDiffIndex(a, b) {\n// const short = Math.min(a.length, b.length);\n// for (let i = 0; i < short; i++) {\n// if (a[i] !== b[i]) {\n// return i;\n// }\n// }\n// if (a.length !== b.length) {\n// return short;\n// }\n// return -1;\n// }\n\nfunction parseArray(text) {\n return text.replace(/\\r/g, \"\").split(\"\\n\").map(s => s.trim()).filter(s => s);\n}\nfunction formatArray(arr) {\n return arr.concat(\"\").join(\"\\n\");\n}\nfunction getMatches(regex, input, group = 0) {\n const matches = [];\n let m;\n while (m = regex.exec(input)) {\n matches.push(m[group]);\n }\n return matches;\n}\n\n// export function getStringSize(value) {\n// return value.length * 2;\n// }\n\nfunction formatCSS(text) {\n function trimLeft(text) {\n return text.replace(/^\\s+/, \"\");\n }\n function getIndent(depth) {\n if (depth === 0) {\n return \"\";\n }\n return \" \".repeat(4 * depth);\n }\n\n // Dont execute this kind of Regex on large CSS, as this isn't necessary.\n // Maxium of 50K characters.\n if (text.length < 50000) {\n const emptyRuleRegexp = /[^{}]+{\\s*}/;\n while (emptyRuleRegexp.test(text)) {\n text = text.replace(emptyRuleRegexp, \"\");\n }\n }\n const css = text.replace(/\\s{2,}/g, \" \") // Replacing multiple spaces to one\n .replace(/\\{/g, \"{\\n\") // {\n .replace(/\\}/g, \"\\n}\\n\") // }\n .replace(/\\;(?![^\\(|\\\"]*(\\)|\\\"))/g, \";\\n\") // ; and do not target between () and \"\"\n .replace(/\\,(?![^\\(|\\\"]*(\\)|\\\"))/g, \",\\n\") // , and do not target between () and \"\"\n .replace(/\\n\\s*\\n/g, \"\\n\") // Remove \\n Without any characters between it to the next \\n\n .split(\"\\n\");\n let depth = 0;\n const formatted = [];\n for (let x = 0, len = css.length; x < len; x++) {\n const line = `${css[x]}\\n`;\n if (line.includes(\"{\")) {\n // {\n formatted.push(getIndent(depth++) + trimLeft(line));\n } else if (line.includes(\"}\")) {\n // }\n formatted.push(getIndent(--depth) + trimLeft(line));\n } else {\n // CSS line\n formatted.push(getIndent(depth) + trimLeft(line));\n }\n }\n return formatted.join(\"\").trim();\n}\nfunction getParenthesesRange(input, searchStartIndex = 0) {\n const length = input.length;\n let depth = 0;\n let firstOpenIndex = -1;\n for (let i = searchStartIndex; i < length; i++) {\n if (depth === 0) {\n const openIndex = input.indexOf(\"(\", i);\n if (openIndex < 0) {\n break;\n }\n firstOpenIndex = openIndex;\n depth++;\n i = openIndex;\n } else {\n const closingIndex = input.indexOf(\")\", i);\n if (closingIndex < 0) {\n break;\n }\n const openIndex = input.indexOf(\"(\", i);\n if (openIndex < 0 || closingIndex < openIndex) {\n depth--;\n if (depth === 0) {\n return {\n start: firstOpenIndex,\n end: closingIndex + 1\n };\n }\n i = closingIndex;\n } else {\n depth++;\n i = openIndex;\n }\n }\n }\n return null;\n}\n\n//# sourceURL=webpack://dark-mode/./src/utils/text.js?"); |
| 300 |
|
| 301 |
/***/ }), |
| 302 |
|
| 303 |
/***/ "./src/utils/throttle.js": |
| 304 |
/*!*******************************!*\ |
| 305 |
!*** ./src/utils/throttle.js ***! |
| 306 |
\*******************************/ |
| 307 |
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { |
| 308 |
|
| 309 |
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ createAsyncTasksQueue: () => (/* binding */ createAsyncTasksQueue),\n/* harmony export */ throttle: () => (/* binding */ throttle)\n/* harmony export */ });\nfunction throttle(callback) {\n let pending = false;\n let frameId = null;\n let lastArgs;\n const throttled = (...args) => {\n lastArgs = args;\n if (frameId) {\n pending = true;\n } else {\n callback(...lastArgs);\n frameId = requestAnimationFrame(() => {\n frameId = null;\n if (pending) {\n callback(...lastArgs);\n pending = false;\n }\n });\n }\n };\n const cancel = () => {\n // TODO: reove cast once types are updated\n cancelAnimationFrame(frameId);\n pending = false;\n frameId = null;\n };\n return Object.assign(throttled, {\n cancel\n });\n}\nfunction createAsyncTasksQueue() {\n const tasks = [];\n let frameId = null;\n function runTasks() {\n let task;\n while (task = tasks.shift()) {\n task();\n }\n frameId = null;\n }\n function add(task) {\n tasks.push(task);\n if (!frameId) {\n frameId = requestAnimationFrame(runTasks);\n }\n }\n function cancel() {\n tasks.splice(0);\n // TODO: reove cast once types are updated\n cancelAnimationFrame(frameId);\n frameId = null;\n }\n return {\n add,\n cancel\n };\n}\n\n//# sourceURL=webpack://dark-mode/./src/utils/throttle.js?"); |
| 310 |
|
| 311 |
/***/ }), |
| 312 |
|
| 313 |
/***/ "./src/utils/time.js": |
| 314 |
/*!***************************!*\ |
| 315 |
!*** ./src/utils/time.js ***! |
| 316 |
\***************************/ |
| 317 |
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { |
| 318 |
|
| 319 |
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ getDuration: () => (/* binding */ getDuration)\n/* harmony export */ });\n// export function parseTime($time) {\n// const parts = $time.split(\":\").slice(0, 2);\n// const lowercased = $time.trim().toLowerCase();\n// const isAM = lowercased.endsWith(\"am\") || lowercased.endsWith(\"a.m.\");\n// const isPM = lowercased.endsWith(\"pm\") || lowercased.endsWith(\"p.m.\");\n\n// let hours = parts.length > 0 ? parseInt(parts[0]) : 0;\n// if (isNaN(hours) || hours > 23) {\n// hours = 0;\n// }\n// if (isAM && hours === 12) {\n// hours = 0;\n// }\n// if (isPM && hours < 12) {\n// hours += 12;\n// }\n\n// let minutes = parts.length > 1 ? parseInt(parts[1]) : 0;\n// if (isNaN(minutes) || minutes > 59) {\n// minutes = 0;\n// }\n\n// return [hours, minutes];\n// }\n\n// function parse24HTime(time) {\n// return time.split(\":\").map((x) => parseInt(x));\n// }\n\n// function compareTime(time1, time2) {\n// if (time1[0] === time2[0] && time1[1] === time2[1]) {\n// return 0;\n// }\n// if (time1[0] < time2[0] || (time1[0] === time2[0] && time1[1] < time2[1])) {\n// return -1;\n// }\n// return 1;\n// }\n\n// export function nextTimeInterval(time0, time1, date = new Date()) {\n// const a = parse24HTime(time0);\n// const b = parse24HTime(time1);\n// const t = [date.getHours(), date.getMinutes()];\n\n// // Ensure a <= b\n// if (compareTime(a, b) > 0) {\n// return nextTimeInterval(time1, time0, date);\n// }\n\n// if (compareTime(a, b) === 0) {\n// return null;\n// }\n\n// if (compareTime(t, a) < 0) {\n// // t < a <= b\n// // Schedule for todate at time a\n// date.setHours(a[0]);\n// date.setMinutes(a[1]);\n// date.setSeconds(0);\n// date.setMilliseconds(0);\n// return date.getTime();\n// }\n\n// if (compareTime(t, b) < 0) {\n// // a <= t < b\n// // Schedule for today at time b\n// date.setHours(b[0]);\n// date.setMinutes(b[1]);\n// date.setSeconds(0);\n// date.setMilliseconds(0);\n// return date.getTime();\n// }\n\n// // a <= b <= t\n// // Schedule for tomorrow at time a\n// return new Date(date.getFullYear(), date.getMonth(), date.getDate() + 1, a[0], a[1]).getTime();\n// }\n\n// export function isInTimeIntervalLocal(time0, time1, date = new Date()) {\n// const a = parse24HTime(time0);\n// const b = parse24HTime(time1);\n// const t = [date.getHours(), date.getMinutes()];\n// if (compareTime(a, b) > 0) {\n// return compareTime(a, t) <= 0 || compareTime(t, b) < 0;\n// }\n// return compareTime(a, t) <= 0 && compareTime(t, b) < 0;\n// }\n\n// function isInTimeIntervalUTC(time0, time1, timestamp) {\n// if (time1 < time0) {\n// return timestamp <= time1 || time0 <= timestamp;\n// }\n// return time0 < timestamp && timestamp < time1;\n// }\n\nfunction getDuration(time) {\n let duration = 0;\n if (time.seconds) {\n duration += time.seconds * 1000;\n }\n if (time.minutes) {\n duration += time.minutes * 60 * 1000;\n }\n if (time.hours) {\n duration += time.hours * 60 * 60 * 1000;\n }\n if (time.days) {\n duration += time.days * 24 * 60 * 60 * 1000;\n }\n return duration;\n}\n\n// export function getDurationInMinutes(time) {\n// return getDuration(time) / 1000 / 60;\n// }\n\n// function getSunsetSunriseUTCTime(latitude, longitude, date) {\n// const dec31 = Date.UTC(date.getUTCFullYear(), 0, 0, 0, 0, 0, 0);\n// const oneDay = getDuration({ days: 1 });\n// const dayOfYear = Math.floor((date.getTime() - dec31) / oneDay);\n\n// const zenith = 90.83333333333333;\n// const D2R = Math.PI / 180;\n// const R2D = 180 / Math.PI;\n\n// // convert the longitude to hour value and calculate an approximate time\n// const lnHour = longitude / 15;\n\n// function getTime(isSunrise) {\n// const t = dayOfYear + ((isSunrise ? 6 : 18) - lnHour) / 24;\n\n// // calculate the Sun's mean anomaly\n// const M = 0.9856 * t - 3.289;\n\n// // calculate the Sun's true longitude\n// let L = M + 1.916 * Math.sin(M * D2R) + 0.02 * Math.sin(2 * M * D2R) + 282.634;\n// if (L > 360) {\n// L -= 360;\n// } else if (L < 0) {\n// L += 360;\n// }\n\n// // calculate the Sun's right ascension\n// let RA = R2D * Math.atan(0.91764 * Math.tan(L * D2R));\n// if (RA > 360) {\n// RA -= 360;\n// } else if (RA < 0) {\n// RA += 360;\n// }\n\n// // right ascension value needs to be in the same qua\n// const Lquadrant = Math.floor(L / 90) * 90;\n// const RAquadrant = Math.floor(RA / 90) * 90;\n// RA += Lquadrant - RAquadrant;\n\n// // right ascension value needs to be converted into hours\n// RA /= 15;\n\n// // calculate the Sun's declination\n// const sinDec = 0.39782 * Math.sin(L * D2R);\n// const cosDec = Math.cos(Math.asin(sinDec));\n\n// // calculate the Sun's local hour angle\n// const cosH =\n// (Math.cos(zenith * D2R) - sinDec * Math.sin(latitude * D2R)) /\n// (cosDec * Math.cos(latitude * D2R));\n// if (cosH > 1) {\n// // always night\n// return {\n// alwaysDay: false,\n// alwaysNight: true,\n// time: 0,\n// };\n// } else if (cosH < -1) {\n// // always day\n// return {\n// alwaysDay: true,\n// alwaysNight: false,\n// time: 0,\n// };\n// }\n\n// const H = (isSunrise ? 360 - R2D * Math.acos(cosH) : R2D * Math.acos(cosH)) / 15;\n\n// // calculate local mean time of rising/setting\n// const T = H + RA - 0.06571 * t - 6.622;\n\n// // adjust back to UTC\n// let UT = T - lnHour;\n// if (UT > 24) {\n// UT -= 24;\n// } else if (UT < 0) {\n// UT += 24;\n// }\n\n// // convert to milliseconds\n// return {\n// alwaysDay: false,\n// alwaysNight: false,\n// time: Math.round(UT * getDuration({ hours: 1 })),\n// };\n// }\n\n// const sunriseTime = getTime(true);\n// const sunsetTime = getTime(false);\n\n// if (sunriseTime.alwaysDay || sunsetTime.alwaysDay) {\n// return {\n// alwaysDay: true,\n// alwaysNight: false,\n// sunriseTime: 0,\n// sunsetTime: 0,\n// };\n// } else if (sunriseTime.alwaysNight || sunsetTime.alwaysNight) {\n// return {\n// alwaysDay: false,\n// alwaysNight: true,\n// sunriseTime: 0,\n// sunsetTime: 0,\n// };\n// }\n\n// return {\n// alwaysDay: false,\n// alwaysNight: false,\n// sunriseTime: sunriseTime.time,\n// sunsetTime: sunsetTime.time,\n// };\n// }\n\n// export function isNightAtLocation(latitude, longitude, date = new Date()) {\n// const time = getSunsetSunriseUTCTime(latitude, longitude, date);\n\n// if (time.alwaysDay) {\n// return false;\n// } else if (time.alwaysNight) {\n// return true;\n// }\n\n// const sunriseTime = time.sunriseTime;\n// const sunsetTime = time.sunsetTime;\n// const currentTime =\n// date.getUTCHours() * getDuration({ hours: 1 }) +\n// date.getUTCMinutes() * getDuration({ minutes: 1 }) +\n// date.getUTCSeconds() * getDuration({ seconds: 1 }) +\n// date.getUTCMilliseconds();\n\n// return isInTimeIntervalUTC(sunsetTime, sunriseTime, currentTime);\n// }\n\n// export function nextTimeChangeAtLocation(latitude, longitude, date = new Date()) {\n// const time = getSunsetSunriseUTCTime(latitude, longitude, date);\n\n// if (time.alwaysDay) {\n// return date.getTime() + getDuration({ days: 1 });\n// } else if (time.alwaysNight) {\n// return date.getTime() + getDuration({ days: 1 });\n// }\n\n// const [firstTimeOnDay, lastTimeOnDay] =\n// time.sunriseTime < time.sunsetTime\n// ? [time.sunriseTime, time.sunsetTime]\n// : [time.sunsetTime, time.sunriseTime];\n// const currentTime =\n// date.getUTCHours() * getDuration({ hours: 1 }) +\n// date.getUTCMinutes() * getDuration({ minutes: 1 }) +\n// date.getUTCSeconds() * getDuration({ seconds: 1 }) +\n// date.getUTCMilliseconds();\n\n// if (currentTime <= firstTimeOnDay) {\n// // Timeline:\n// // --- firstTimeOnDay <---> lastTimeOnDay ---\n// // ^\n// // Current time\n// return Date.UTC(\n// date.getUTCFullYear(),\n// date.getUTCMonth(),\n// date.getUTCDate(),\n// 0,\n// 0,\n// 0,\n// firstTimeOnDay\n// );\n// }\n// if (currentTime <= lastTimeOnDay) {\n// // Timeline:\n// // --- firstTimeOnDay <---> lastTimeOnDay ---\n// // ^\n// // Current time\n// return Date.UTC(\n// date.getUTCFullYear(),\n// date.getUTCMonth(),\n// date.getUTCDate(),\n// 0,\n// 0,\n// 0,\n// lastTimeOnDay\n// );\n// }\n// // Timeline:\n// // --- firstTimeOnDay <---> lastTimeOnDay ---\n// // ^\n// // Current time\n// return Date.UTC(\n// date.getUTCFullYear(),\n// date.getUTCMonth(),\n// date.getUTCDate() + 1,\n// 0,\n// 0,\n// 0,\n// firstTimeOnDay\n// );\n// }\n\n//# sourceURL=webpack://dark-mode/./src/utils/time.js?"); |
| 320 |
|
| 321 |
/***/ }), |
| 322 |
|
| 323 |
/***/ "./src/utils/url.js": |
| 324 |
/*!**************************!*\ |
| 325 |
!*** ./src/utils/url.js ***! |
| 326 |
\**************************/ |
| 327 |
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { |
| 328 |
|
| 329 |
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ compareURLPatterns: () => (/* binding */ compareURLPatterns),\n/* harmony export */ fullyQualifiedDomainMatchesWildcard: () => (/* binding */ fullyQualifiedDomainMatchesWildcard),\n/* harmony export */ getAbsoluteURL: () => (/* binding */ getAbsoluteURL),\n/* harmony export */ isFullyQualifiedDomainWildcard: () => (/* binding */ isFullyQualifiedDomainWildcard),\n/* harmony export */ isRelativeHrefOnAbsolutePath: () => (/* binding */ isRelativeHrefOnAbsolutePath),\n/* harmony export */ isURLInList: () => (/* binding */ isURLInList),\n/* harmony export */ isURLMatched: () => (/* binding */ isURLMatched),\n/* harmony export */ parseURL: () => (/* binding */ parseURL),\n/* harmony export */ parsedURLCache: () => (/* binding */ parsedURLCache)\n/* harmony export */ });\n/* harmony import */ var _ipv6__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./ipv6 */ \"./src/utils/ipv6.js\");\n\nlet anchor;\nconst parsedURLCache = new Map();\nfunction fixBaseURL($url) {\n if (!anchor) {\n anchor = document.createElement(\"a\");\n }\n anchor.href = $url;\n return anchor.href;\n}\nfunction parseURL($url, $base = null) {\n const key = `${$url}${$base ? `;${$base}` : \"\"}`;\n if (parsedURLCache.has(key)) {\n return parsedURLCache.get(key);\n }\n if ($base) {\n const parsedURL = new URL($url, fixBaseURL($base));\n parsedURLCache.set(key, parsedURL);\n return parsedURL;\n }\n const parsedURL = new URL(fixBaseURL($url));\n parsedURLCache.set($url, parsedURL);\n return parsedURL;\n}\nfunction getAbsoluteURL($base, $relative) {\n if ($relative.match(/^data\\\\?\\:/)) {\n return $relative;\n }\n // Check if relative starts with `//hostname...`.\n // We have to add a protocol to make it absolute.\n if (/^\\/\\//.test($relative)) {\n return `${location.protocol}${$relative}`;\n }\n const b = parseURL($base);\n const a = parseURL($relative, b.href);\n return a.href;\n}\n\n// Check if any relative URL is on the window.location;\n// So that https://duck.com/ext.css would return true on https://duck.com/\n// But https://duck.com/styles/ext.css would return false on https://duck.com/\n// Visa versa https://duck.com/ext.css should return fasle on https://duck.com/search/\n// We're checking if any relative value within ext.css could potentially not be on the same path.\nfunction isRelativeHrefOnAbsolutePath(href) {\n if (href.startsWith(\"data:\")) {\n return true;\n }\n const url = parseURL(href);\n if (url.protocol !== location.protocol) {\n return false;\n }\n if (url.hostname !== location.hostname) {\n return false;\n }\n if (url.port !== location.port) {\n return false;\n }\n // Now check if the path is on the same path as the base\n // We do this by getting the pathname up until the last slash.\n return url.pathname === location.pathname;\n}\n\n// export function getURLHostOrProtocol($url) {\n// const url = new URL($url);\n// if (url.host) {\n// return url.host;\n// } else if (url.protocol === \"file:\") {\n// return url.pathname;\n// }\n// return url.protocol;\n// }\n\nfunction compareURLPatterns(a, b) {\n return a.localeCompare(b);\n}\n\n/**\n * Determines whether URL has a match in URL template list.\n * @param url Site URL.\n * @paramlist List to search into.\n */\nfunction isURLInList(url, list) {\n for (let i = 0; i < list.length; i++) {\n if (isURLMatched(url, list[i])) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Determines whether URL matches the template.\n * @param url URL.\n * @param urlTemplate URL template (\"google.*\", \"youtube.com\" etc).\n */\nfunction isURLMatched(url, urlTemplate) {\n const isFirstIPV6 = (0,_ipv6__WEBPACK_IMPORTED_MODULE_0__.isIPV6)(url);\n const isSecondIPV6 = (0,_ipv6__WEBPACK_IMPORTED_MODULE_0__.isIPV6)(urlTemplate);\n if (isFirstIPV6 && isSecondIPV6) {\n return (0,_ipv6__WEBPACK_IMPORTED_MODULE_0__.compareIPV6)(url, urlTemplate);\n } else if (!isFirstIPV6 && !isSecondIPV6) {\n const regex = createUrlRegex(urlTemplate);\n return regex !== null && Boolean(url.match(regex));\n }\n return false;\n}\nfunction createUrlRegex(urlTemplate) {\n try {\n urlTemplate = urlTemplate.trim();\n const exactBeginning = urlTemplate[0] === \"^\";\n const exactEnding = urlTemplate[urlTemplate.length - 1] === \"$\";\n const hasLastSlash = /\\/\\$?$/.test(urlTemplate);\n urlTemplate = urlTemplate.replace(/^\\^/, \"\") // Remove ^ at start\n .replace(/\\$$/, \"\") // Remove $ at end\n .replace(/^.*?\\/{2,3}/, \"\") // Remove scheme\n .replace(/\\?.*$/, \"\") // Remove query\n .replace(/\\/$/, \"\"); // Remove last slash\n\n let slashIndex;\n let beforeSlash;\n let afterSlash;\n if ((slashIndex = urlTemplate.indexOf(\"/\")) >= 0) {\n beforeSlash = urlTemplate.substring(0, slashIndex); // google.*\n afterSlash = urlTemplate.replace(/\\$/g, \"\").substring(slashIndex); // /login/abc\n } else {\n beforeSlash = urlTemplate.replace(/\\$/g, \"\");\n }\n\n //\n // SCHEME and SUBDOMAINS\n\n let result = exactBeginning ? \"^(.*?\\\\:\\\\/{2,3})?\" // Scheme\n : \"^(.*?\\\\:\\\\/{2,3})?([^/]*?\\\\.)?\"; // Scheme and subdomains\n\n //\n // HOST and PORT\n\n const hostParts = beforeSlash.split(\".\");\n result += \"(\";\n for (let i = 0; i < hostParts.length; i++) {\n if (hostParts[i] === \"*\") {\n hostParts[i] = \"[^\\\\.\\\\/]+?\";\n }\n }\n result += hostParts.join(\"\\\\.\");\n result += \")\";\n\n //\n // PATH and QUERY\n\n if (afterSlash) {\n result += \"(\";\n result += afterSlash.replace(\"/\", \"\\\\/\");\n result += \")\";\n }\n result += exactEnding ? \"(\\\\/?(\\\\?[^/]*?)?)$\" // All following queries\n : `(\\\\/${hasLastSlash ? \"\" : \"?\"}.*?)$`; // All following paths and queries\n\n //\n // Result\n\n return new RegExp(result, \"i\");\n } catch (e) {\n return null;\n }\n}\n\n// export function isFullyQualifiedDomain(candidate) {\n// return /^[a-z0-9\\.\\-]+$/i.test(candidate) && candidate.indexOf(\"..\") === -1;\n// }\n\nfunction isFullyQualifiedDomainWildcard(candidate) {\n if (!candidate.includes(\"*\") || !/^[a-z0-9\\.\\-\\*]+$/i.test(candidate)) {\n return false;\n }\n const labels = candidate.split(\".\");\n for (const label of labels) {\n if (label !== \"*\" && !/^[a-z0-9\\-]+$/i.test(label)) {\n return false;\n }\n }\n return true;\n}\nfunction fullyQualifiedDomainMatchesWildcard(wildcard, candidate) {\n const wildcardLabels = wildcard.toLowerCase().split(\".\");\n const candidateLabels = candidate.toLowerCase().split(\".\");\n if (candidateLabels.length < wildcardLabels.length) {\n return false;\n }\n while (wildcardLabels.length) {\n const wildcardLabel = wildcardLabels.pop();\n const candidateLabel = candidateLabels.pop();\n if (wildcardLabel !== \"*\" && wildcardLabel !== candidateLabel) {\n return false;\n }\n }\n return true;\n}\n\n//# sourceURL=webpack://dark-mode/./src/utils/url.js?"); |
| 330 |
|
| 331 |
/***/ }), |
| 332 |
|
| 333 |
/***/ "./src/utils/visibility.js": |
| 334 |
/*!*********************************!*\ |
| 335 |
!*** ./src/utils/visibility.js ***! |
| 336 |
\*********************************/ |
| 337 |
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { |
| 338 |
|
| 339 |
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ documentIsVisible: () => (/* binding */ documentIsVisible),\n/* harmony export */ removeDocumentVisibilityListener: () => (/* binding */ removeDocumentVisibilityListener),\n/* harmony export */ setDocumentVisibilityListener: () => (/* binding */ setDocumentVisibilityListener)\n/* harmony export */ });\n/**\n * The following code contains a workaround for extensions designed to prevent page from knowing when it is hidden\n * GitHub issue: https://github.com/darkreader/darkreader/issues/10004\n * GitHub PR: https://github.com/darkreader/darkreader/pull/10047\n *\n * Doue to the intntional breakage introduced by these extensions, this utility might incorrecly report that document\n * is visible while it is not, but it will never report document as hidden while it is visible.\n *\n * This code exploits the fact that most such extensions block only a subset of Page Lifecycle API,\n * which notifies page of being hidden but not of being shown, while Dark Reader really cares only about\n * page being shown.\n * Specifically:\n * - extensions block visibilitychange and blur event\n * - extensions do not block focus event; browsers deliver focus event when user switches to\n * a previously hidden tab or previously hidden window (assuming DevTools are closed so window gets the focus)\n * if document has focus, then we can assume that it is visible\n * - some extensions overwrite document.hidden but not document.visibilityState\n * - Firefox has a bug: if extension overwrites document.hidden and document.visibilityState via Object.defineProperty,\n * then Firefox will reset them to true and 'hidden' when tab is activated, but document.hasFocus() will be true\n * - Safari supports document.visibilityState === 'prerender' which makes document.hidden === true even when document\n * is visible to the user\n *\n * Note: This utility supports adding only one callback since currently calling code sets only one listener and Firefox\n * has issues optimizing code with multiple callbacks stored in array or in a set.\n */\n\nlet documentVisibilityListener = null;\nlet documentIsVisible_ = !document.hidden;\n\n// TODO: use EventListenerOptions class once it is updated\nconst listenerOptions = {\n capture: true,\n passive: true\n};\nfunction watchForDocumentVisibility() {\n document.addEventListener(\"visibilitychange\", documentVisibilityListener, listenerOptions);\n window.addEventListener(\"pageshow\", documentVisibilityListener, listenerOptions);\n window.addEventListener(\"focus\", documentVisibilityListener, listenerOptions);\n}\nfunction stopWatchingForDocumentVisibility() {\n document.removeEventListener(\"visibilitychange\", documentVisibilityListener, listenerOptions);\n window.removeEventListener(\"pageshow\", documentVisibilityListener, listenerOptions);\n window.removeEventListener(\"focus\", documentVisibilityListener, listenerOptions);\n}\nfunction setDocumentVisibilityListener(callback) {\n const alreadyWatching = Boolean(documentVisibilityListener);\n documentVisibilityListener = () => {\n if (!document.hidden) {\n removeDocumentVisibilityListener();\n callback();\n documentIsVisible_ = true;\n }\n };\n if (!alreadyWatching) {\n watchForDocumentVisibility();\n }\n}\nfunction removeDocumentVisibilityListener() {\n stopWatchingForDocumentVisibility();\n documentVisibilityListener = null;\n}\nfunction documentIsVisible() {\n return documentIsVisible_;\n}\n\n//# sourceURL=webpack://dark-mode/./src/utils/visibility.js?"); |
| 340 |
|
| 341 |
/***/ }) |
| 342 |
|
| 343 |
/******/ }); |
| 344 |
/************************************************************************/ |
| 345 |
/******/ // The module cache |
| 346 |
/******/ var __webpack_module_cache__ = {}; |
| 347 |
/******/ |
| 348 |
/******/ // The require function |
| 349 |
/******/ function __webpack_require__(moduleId) { |
| 350 |
/******/ // Check if module is in cache |
| 351 |
/******/ var cachedModule = __webpack_module_cache__[moduleId]; |
| 352 |
/******/ if (cachedModule !== undefined) { |
| 353 |
/******/ return cachedModule.exports; |
| 354 |
/******/ } |
| 355 |
/******/ // Create a new module (and put it into the cache) |
| 356 |
/******/ var module = __webpack_module_cache__[moduleId] = { |
| 357 |
/******/ // no module.id needed |
| 358 |
/******/ // no module.loaded needed |
| 359 |
/******/ exports: {} |
| 360 |
/******/ }; |
| 361 |
/******/ |
| 362 |
/******/ // Execute the module function |
| 363 |
/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); |
| 364 |
/******/ |
| 365 |
/******/ // Return the exports of the module |
| 366 |
/******/ return module.exports; |
| 367 |
/******/ } |
| 368 |
/******/ |
| 369 |
/************************************************************************/ |
| 370 |
/******/ /* webpack/runtime/define property getters */ |
| 371 |
/******/ (() => { |
| 372 |
/******/ // define getter functions for harmony exports |
| 373 |
/******/ __webpack_require__.d = (exports, definition) => { |
| 374 |
/******/ for(var key in definition) { |
| 375 |
/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { |
| 376 |
/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); |
| 377 |
/******/ } |
| 378 |
/******/ } |
| 379 |
/******/ }; |
| 380 |
/******/ })(); |
| 381 |
/******/ |
| 382 |
/******/ /* webpack/runtime/hasOwnProperty shorthand */ |
| 383 |
/******/ (() => { |
| 384 |
/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) |
| 385 |
/******/ })(); |
| 386 |
/******/ |
| 387 |
/******/ /* webpack/runtime/make namespace object */ |
| 388 |
/******/ (() => { |
| 389 |
/******/ // define __esModule on exports |
| 390 |
/******/ __webpack_require__.r = (exports) => { |
| 391 |
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { |
| 392 |
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); |
| 393 |
/******/ } |
| 394 |
/******/ Object.defineProperty(exports, '__esModule', { value: true }); |
| 395 |
/******/ }; |
| 396 |
/******/ })(); |
| 397 |
/******/ |
| 398 |
/************************************************************************/ |
| 399 |
/******/ |
| 400 |
/******/ // startup |
| 401 |
/******/ // Load entry module and return exports |
| 402 |
/******/ // This entry module can't be inlined because the eval devtool is used. |
| 403 |
/******/ var __webpack_exports__ = __webpack_require__("./index.js"); |
| 404 |
/******/ |
| 405 |
/******/ })() |
| 406 |
; |