// ==UserScript== // @name Eink Polish Beta // @namespace http://tampermonkey.net/ // @version 3.3 // @description 优化网页与第三方浏览器插件在 eink 设备上的显示。禁用 transition、animation、box-shadow、filter。加重字体。添加边框。 // @author chen // @match https://*/* // @exclude https://vscode.dev/* // @exclude https://gemini.google.com/* // @exclude https://chatgpt.com/* // @exclude https://developer.mozilla.org/* // @run-at document-start // @downloadURL https://update.greasyfork.icu/scripts/570213/Eink%20Polish%20Beta.user.js // @updateURL https://update.greasyfork.icu/scripts/570213/Eink%20Polish%20Beta.meta.js // ==/UserScript== (function () { 'use strict'; // 开启严格模式,让浏览器更规范地执行代码 // 1. 定义我们要强制生效的 CSS 样式 const hostname = window.location.hostname; // 比如 "www.youtube.com" const config = { "*": { "css": ` div { /* --- 基础清理:禁用动画和特效 --- */ transition-duration: 0.001s !important; /* 禁用所有渐变过渡, 不可以设置为 none, 小红书图片翻页会出现问题 */ transition-delay: 0s !important; animation-duration: 0s !important; /* 禁用所有动画, Gemini 推荐不要设置为 none, 会在少数情况出现问题 */ animation-delay: 0s !important; box-shadow: none !important; /* 禁用所有元素阴影 */ filter: none !important; /* 禁用所有滤镜(比如模糊效果) */ /* --- 控件 --- */ // border-color: #333333 !important; /* 让边框变成深色,防止按钮背景变白后找不到按钮在哪里 */ } p, h1, h2, h3, h4, h5, h6, li { font-weight: 600 !important; /* 加粗,提高墨水屏上的辨识度 */ // color: #000 !important; /* 强制纯黑文字 */ // -webkit-text-stroke: 0.5px white; /* 白色描边 */ // paint-order: stroke fill; /* 白色描边不会侵占原本字体 */ } span, div, a { font-weight: 600 !important; } `, "shadowCss": ` div { /* --- 基础清理:禁用动画和特效 --- */ transition: none !important; /* 禁用所有渐变过渡, 不可以设置为 none, 小红书图片翻页会出现问题 */ animation: none !important; /* 禁用所有动画, Gemini 推荐不要设置为 none, 会在少数情况出现问题 */ box-shadow: none !important; /* 禁用所有元素阴影 */ filter: none !important; /* 禁用所有滤镜(比如模糊效果) */ /* --- 控件 --- */ border-color: #333333 !important; /* 让边框变成深色,防止按钮背景变白后找不到按钮在哪里 */ } ` }, "*.substack.com": { "css": ` p { color: #000 !important; /* 强制纯黑文字 */ } ` }, // "jetbrains.com": { // "css": ` // p, h1, h2, h3, h4, h5, h6 { // font-weight: 600 !important; /* 加粗,提高墨水屏上的辨识度 */ // color: #000 !important; /* 强制纯黑文字 */ // -webkit-text-stroke: 1px white; /* 白色描边 */ // paint-order: stroke fill; /* 白色描边不会侵占原本字体 */ // } // ` // }, // "*.xiaohongshu.com": { // "css": ` // span { // color: #000 !important; /* 强制纯黑文字 */ // } // ` // } }; /*==== 拼接css ===*/ // 1. 域名匹配与优先级打分函数 function getMatchScore(hostname, ruleKey) { // 优先级 1:全局匹配 "*" if (ruleKey === "*") { return 1; } // 优先级最高:精确匹配 (例如 "mail.google.com" 或 "google.com") // 分数设为 1000,确保它永远在最后被拼接,优先级最高 if (hostname === ruleKey) { return 1000; } // 优先级中等:通配符匹配 (例如 "*.google.com") if (ruleKey.startsWith("*.")) { const baseDomain = ruleKey.slice(2); // 取出 "google.com" // 【重要】只匹配子域名,不匹配主域名(即 *.google.com 不会匹配 google.com) // 这样实现了 *.google.com 和 google.com 分开处理的要求 if (hostname.endsWith('.' + baseDomain)) { // 利用 baseDomain 的长度作为分数,实现通配符间的优先级 // 比如 *.mail.google.com (分数 25) 优先级大于 *.google.com (分数 20) return 10 + baseDomain.length; } } // 0 表示不匹配 return 0; } // ========================================== // 2. 整合调用:收集匹配项 -> 按优先级排序 -> 拼接 // ========================================== let finalCss = config["*"]?.css || ""; let finalShadowCss = config["*"]?.shadowCss || ""; let matchedRules = []; // 用于存放当前域名匹配到的所有规则 // 遍历所有的配置规则 Object.keys(config).forEach(key => { const score = getMatchScore(hostname, key); // 如果 score > 0,说明匹配成功,存入数组 if (score > 0) { matchedRules.push({ key: key, score: score, css: config[key].css, shadowCss: config[key].shadowCss }); } }); // 按优先级升序排序 (分数小的在前面,分数大的在后面覆盖) matchedRules.sort((a, b) => a.score - b.score); // 按照排好的顺序拼接 CSS matchedRules.forEach(rule => { if (rule.css) { finalCss += `\n/* From ${rule.key} (Priority: ${rule.score}) */\n${rule.css}`; } if (rule.shadowCss) { finalShadowCss += `\n/* From ${rule.key} (Shadow, Priority: ${rule.score}) */\n${rule.shadowCss}`; } }); // 此时 finalCss 和 finalShadowCss 已经完成了拼接,高优先级的在最底下 // 2. 核心动作:把上面的 CSS 注入到指定的“区域” function injectStyle(target, css) { // 如果这个区域已经打过我们留下的标记,说明注入过了,直接跳过,防止重复添加 if (target.__styleInjected) return; // 创建一个