您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
实时替换页面中的文本,包括 shadow-root 内的文本
// ==UserScript== // @name fontra汉化(文本替换) // @namespace https://github.com/Losketch // @version 1.0.0 // @author Losketch // @description 实时替换页面中的文本,包括 shadow-root 内的文本 // @match *localhost:8000/editor/-/* // @match *localhost:8000/fontinfo/-/* // @match *localhost:8000/plugins/plugins.html // @icon data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMjAwIDEyMDAiPjxwYXRoIGZpbGw9IiNGMjE4NTkiIGQ9Ik0wIDg3MFYzMzBDMCAxNDggMTQ4IDAgMzMwIDBoNTQwYzE4MiAwIDMzMCAxNDggMzMwIDMzMHY1NDBjMCAxODItMTQ4IDMzMC0zMzAgMzMwSDMzMEEzMzAgMzMwIDAgMCAxIDAgODcwWm0wIDAiLz48Y2xpcFBhdGggaWQ9ImEiPjxwYXRoIGQ9Ik0wIDN2NGMwIDIgMSAzIDMgM2g0YzIgMCAzLTEgMy0zVjNjMC0yLTEtMy0zLTNIM0MxIDAgMCAxIDAgM1ptMCAwIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIHRyYW5zZm9ybT0ibWF0cml4KDEyMCAwIDAgLTEyMCAwIDEyMDApIi8+PC9jbGlwUGF0aD48ZyBjbGlwLXBhdGg9InVybCgjYSkiPjxwYXRoIGZpbGw9IiNDNDEzNTMiIGQ9Im0yNTMgMjc4LTg1IDg1djEyMGgxNTB2Mzk1aC02NWwtODUgODV2MTIwaDUyOGw4NS04NVY4NzhINjEzdi04M2gxODVsODUtODVWNjAzaDY1bDg1LTg1VjI3OFptMzYwIDMxMlY0ODNoMjE1djEwN1ptMCAwIi8+PHBhdGggZmlsbD0iIzA0MjMyRCIgZD0iTTMxOCAzMTNIMTY4bDg1IDg1aDY1Wm01MTAgMEg1MjhsODUgODVoMjE1Wm0wIDEyMCA4NSA4NWgxMjBsLTg1LTg1Wk01MjggNjI1bDg1IDg1aDI3MGwtODUtODVaTTE2OCA5MTNsODUgODVoNTI4bC04NS04NVptMCAwIi8+PHBhdGggZmlsbD0iIzA5NEE1RSIgZD0ibTk0OCA0MzMgODUgODVWMjc4bC04NS04NVptLTMzNS0zNS04NS04NXYxOTJoODVabTE4NSAyMjcgODUgODVWNTkwbC04NS04NVptLTE4NSA4NS04NS04NXYxNjhoODVabTgzIDIwMyA4NSA4NVY4NzhsLTg1LTg1Wm0wIDAiLz48cGF0aCBmaWxsPSIjRkZGIiBkPSJNMTY4IDE5M3YxMjBoMTUwdjQ4MEgxNjh2MTIwaDUyOFY3OTNINTI4VjYyNWgyNzBWNTA1SDUyOFYzMTNoMzAwdjEyMGgxMjBWMTkzWm0wIDAiLz48L2c+PC9zdmc+ // @grant none // @sandbox JavaScript // @license WTFPL // ==/UserScript== (function() { 'use strict'; const translations = { // 上方任务栏 // // 视图 "is not used as a component by any glyph.": " 未被任何字形用作元件。", // 编辑 'Are you sure you want to delete glyph "': '您确定要从字体项目中删除字形 “', 'from the font project?': '”吗?', // 左侧工具栏 // "Display Language": "显示语言", "Fontra version:": "Fontra 版本:", "Python version:": "Python 版本:", "Startup time:": "启动时间:", "View plugins:": "查看插件:", "editor, fontinfo, plugins": "编辑器、字体信息、插件", "Project manager:": "项目管理:", // Designspace 导航 "View options": "查看可选项", "Apply single-axis mapping": "应用单轴映射", "Apply cross-axis mapping": "应用跨轴映射", "Show effective location": "显示有效位置", "Show hidden axes": "显示隐藏轴", "⚠️ The source name should be unique": "⚠️ 源名称应是唯一的", "⚠️ The source location must be unique": "⚠️ 源位置必须是唯一的", "Are you sure you want to delete source": "您确定要删除源", "Also delete associated layer": "同时删除相关层 ", "Edit glyph axes": "编辑字形轴", // 参考字体 "Chinese ; Han (Simplified variant) (zh-Hans)": "中文;汉(简体)(zh-Hans)", "Chinese ; Han (Traditional variant) (zh-Hant)": "中文;汉(繁体)(zh-Hant)", "Chinese ; Hong Kong (zh-HK)": "中文;香港(zh-HK)", "Japanese (ja)": "日本(ja)", "Korean (ko)": "韩国(ko)", // fontinfo 页面 "New font source...": "新字体源...", "Add font source": "添加字体源", "Source name:": "源名称:", "Status definitions": "状态定义", "New status definition": "新状态定义", "Delete status definition": "删除状态定义", "Is Default": "是否为默认值", "If checked, this status will be used as a fallback when a source status is not set": "如果选中,当未设置源状态时,该状态将被用作后备状态", // fontinfo 页面 "Can’t edit glyph “": "无法编辑字形 “", "The font is read-only.": "该字体是只读的。", "The data could not be saved due to an error.": "由于错误,数据无法保存。", "The edit has been reverted.": "编辑内容已被还原。", // 右侧工具栏 // // 选区信息 "Lock glyph": "锁定字形", "Unlock glyph": "解锁字形", "Are you sure you want to unlock glyph": "你确定要解锁字形", // 选区变换 "Distance in units": "距离单位", "Path Operations": "路径操作", "Remove overlaps": "并集", "Subtract contours": "差集", "Intersect contours": "交集", "Exclude contours": "互斥", // Glyph Note "Glyph Note": "字形注释", "Glyph note (no glyph selected)": "字形注释(未选择字形)", "Glyph note for": "字形注释为", // Related Glyphs & Characters "Related Glyphs & Characters": "相关字形和字符", "Related glyphs & characters": "相关字形和字符", "Related glyphs & characters for": "相关字形和字符用于", "(No glyph selected)": "(未选择字形)", "(No related glyphs or characters were found)": "(未找到相关字形或字符)", "Characters that decompose with this character": "与该字符一起分解的字符", "Character decomposition": "字符分解", // plugins // "Fontra plugins": "Fontra 插件", "Add plugin": "添加插件", "Plugin path:": "插件路径", // 其他垫底 "Knife Tool": "刀工具", "Delete source": "删除源", "Add source": "添加源", "Italic Angle": "斜体角度", "Font Info": "字体信息", "Axes": "参数轴", "Sources": "源", "General": "常规", "Location": "位置", "weight": "字重", "slant": "偏", "Line metrics": "边界度量", "Ascender": "上边界", "Cap Height": "上限高", "x-Height": "x轴高", "Baseline": "基线", "Descender": "下边界", "Minimum": "最低", "Default": "默认值", "Maximum": "最大", "Name": "名称", "Layer:": "层:", "Okay": "好的", "Create": "创建", "Cancel": "取消", "Delete": "删除", "Add": "添加", "None": "无", "Yes": "是", "Cut": "剪切", "Copy": "复制", "Paste": "粘贴", }; // 替换文本的函数 function replaceTextInNode(node) { for (const key in translations) { if (node.nodeType === Node.TEXT_NODE && node.textContent.includes(key)) { node.textContent = node.textContent.replace(key, translations[key]); } } } // 替换input标签的value属性 function replaceInputValues(root) { root.querySelectorAll('input').forEach(input => { for (const key in translations) { if (input.value.includes(key)) { input.value = input.value.replace(key, translations[key]); } } }); } // 替换data-tooltip属性 function replaceTooltipAttributes(root) { root.querySelectorAll('[data-tooltip]').forEach(element => { for (const key in translations) { if (element.getAttribute('data-tooltip').includes(key)) { element.setAttribute('data-tooltip', element.getAttribute('data-tooltip').replace(key, translations[key])); } } }); root.querySelectorAll('[title]').forEach(element => { for (const key in translations) { if (element.getAttribute('title').includes(key)) { element.setAttribute('title', element.getAttribute('title').replace(key, translations[key])); } } }); } // 遍历普通节点 function traverseNodes(node) { replaceTextInNode(node); node.childNodes.forEach(traverseNodes); } // 遍历 shadow DOM 节点 function traverseShadowNodes(shadowRoot) { shadowRoot.querySelectorAll('*').forEach(element => { if (element.shadowRoot) { traverseShadowNodes(element.shadowRoot); } element.childNodes.forEach(traverseNodes); }); replaceInputValues(shadowRoot); // 替换shadow DOM节点里的input标签的value属性 replaceTooltipAttributes(shadowRoot); // 替换shadow DOM节点里的data-tooltip属性 } // 定期执行替换操作 setInterval(() => { traverseNodes(document.body); document.querySelectorAll('*').forEach(element => { if (element.shadowRoot) { traverseShadowNodes(element.shadowRoot); } }); replaceInputValues(document); // 替换普通DOM节点里的input标签的value属性 replaceTooltipAttributes(document); // 替换普通DOM节点里的data-tooltip属性 }, 3000); // 每3秒执行一次 })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址