// ==UserScript== // @name 替换网页字体 // @author ai // @version 2.44 // @match *://*/* // @run-at document-start // @early-start // @grant GM_addStyle // @grant GM_getValues // @grant GM_getValue // @grant GM_setValues // @grant GM_setValue // @grant GM_listValues // @grant GM_addValueChangeListener // @grant GM_registerMenuCommand // @grant GM_unregisterMenuCommand // @description 替换网页的字体 // @namespace https://greasyfork.org/users/22620 // ==/UserScript== (function() { 'use strict'; const DEFAULT_CONFIG = { enabled: true, font: '微软雅黑', exclusions: 'code' }; class FontManager { constructor() { GM_addStyle(`:root {--自定义-字体: '';}`); if(!GM_listValues().length) GM_setValues(DEFAULT_CONFIG); GM_listValues().forEach(key => { GM_addValueChangeListener(key, (k, oldV, newV) => { this.config[k] = newV; if (key === "enabled") { this.updateMenu(); this.styleElement.textContent = newV ? this.css : ''; } if (key === "font") { const font = this.WebFonts ? `${newV}, ${this.WebFonts}` : newV; this.changeFont(font); } if (key === "exclusions") { this.css = this.generateCSS(); this.styleElement.textContent = this.config.enabled ? this.css : ''; } }) }); this.config = GM_getValues(DEFAULT_CONFIG); this.css = this.generateCSS(); this.styleElement = GM_addStyle(this.config.enabled ? this.css : ''); this.changeFont(this.config.font); if (window.top === window) this.initMenu(); this.getWebFonts(); } saveConfig(key, value) { if (GM_getValue(key) === value) return; GM_setValue(key, value); } async getWebFonts() { await document.fonts.ready; const fonts = new Set(); document.fonts.forEach(font => fonts.add(`"${font.family}"`)); this.WebFonts = [...fonts].join(','); if (this.WebFonts) this.changeFont(`${this.config.font},${this.WebFonts}`); } generateCSS() { let exclusions = 'i,[class*="ico"],[class*="fa-"],[class*="symbol"]'; if (this.config.exclusions.trim()) exclusions = `${exclusions},${this.config.exclusions}`; return ` @scope (body) to (${exclusions}) { * { font-family: var(--自定义-字体) !important; } } `; } changeFont(font) { document.documentElement.style.setProperty('--自定义-字体', font); } initMenu() { this.menuCommands = new Map(); this.updateMenu(); } updateMenu() { this.menuCommands.forEach(id => GM_unregisterMenuCommand(id)); this.menuCommands.clear(); this.menuCommands.set('enabled', GM_registerMenuCommand( this.config.enabled ? '❌ 禁用字体替换' : '✅ 启用字体替换', () => this.saveConfig("enabled", !this.config.enabled) )); this.menuCommands.set('font', GM_registerMenuCommand('🖋️ 配置字体名称', () => this.promptConfig('font', '请输入新的字体名称') )); this.menuCommands.set('exclusions', GM_registerMenuCommand('🚫 配置排除元素列表', () => this.promptConfig('exclusions', '请输入新的排除元素选择器') )); this.menuCommands.set('reset', GM_registerMenuCommand('🗑️ 恢复默认设置', () => this.resetToDefault() )); } promptConfig(type, promptText) { const current = this.config[type]; const newValue = prompt(`${promptText}:\n(用逗号分隔,例如: ${type === 'font' ? '"微软雅黑", system-ui' : 'i, code'})`, current); if (newValue) this.saveConfig(type, newValue); } resetToDefault() { if (confirm('确定要将所有配置恢复为默认值吗?')) GM_setValues(DEFAULT_CONFIG); } } new FontManager(); })();