全部文章

一个能直接开工的 Chrome 扩展:formant

formant 把翻译、New Tab、书签、代理、站点数据、GitHub 打包、V2EX、自动翻页、鼠标手势收进同一套 Chrome MV3 扩展。设置走 option 面板,密钥放 mono,云端按 Client API Key 隔离。

写一个扩展功能不难。难的是把日常那一堆需求塞进同一个壳子,还别互相踩。

翻译要弹窗和划词,新标签页想看天气汇率,书签得同步到自己的服务。GitHub 偶尔打包下个目录,V2EX 想自动签到,长列表懒得点下一页。代理、扩展开关、站点 Cookie 又不想再装四五套。每样单独装一个,图标能挤满工具栏,权限重复,设置散得到处都是。从零写倒也能写,就是 Service Worker 说停就停、右键菜单互相覆盖、content script 把宿主页样式搞脏,这些坑得反复踩。

formant 是冲着这件事做的。Chrome Manifest V3,原生 HTML / CSS / JS,后台走 Oolaf mono 的 Client API。不是演示按钮那种空壳,常用的已经串进去了。

插件首页

设置用一套 option.html 挂多个面板。总开关在 #features,细节进对应锚点。工具栏图标始终打开 formant popup,不把入口让给某个子模块。后来功能加多了,popup 里也能进书签、站点数据、扩展管理;二级页顶栏统一成返回翻译加当前标题,操作放下面工具条,免得小窗口里再叠一套顶栏。

功能
翻译

密钥不进扩展仓库。本机只存 mono 地址和一把 Client API Key;GPT、百度、天气这些放 Admin 的 Formant 配置组。翻译失败链路也写死了:Google 直连不行走 mono Google,再不行百度。词库打分用合并后的结果,不拿一份静态表当唯一真相。

划词面板、GitHub 下载进度、AutoPagerize 状态条、手势轨迹,尽量都进 Shadow DOM。跟页面通信走 chrome.runtime / chrome.tabs,密钥不塞进 content script。Service Worker 按随时会被杀掉来写,重要状态落 chrome.storage。

代码按模块拆:翻译、词库、New Tab、书签、GitZip、V2EX、自动翻页、代理、扩展管理、站点数据、鼠标手势,各有 bridge 和 option 面板。新能力往面板上挂,不为单项另开独立设置页。自有源码单文件卡在 500 行附近,background 和 popup 不无限胀。

翻译和词库

入口就那些:popup 输入框、划词浮标、右键「用 formant 翻译」。模式有自动 / Google / GPT / 全部。本地打分看脚本、词库和句式,简单的走 Google,绕的可以并行 GPT。原文译文都能读。默认模式和目标语言存在 chrome.storage.local,popup 和划词共用。popup 打开会自动聚焦输入框。

内置俚语翻译

内置 en / zh / ja / ko / tr 俚语包,只读,能停用。自定义包在本机,JSON 导入可以新建、合并、替换。管理在 option.html#lexicon。

词库

New Tab

覆盖浏览器新标签页,布局能同步到 mono。第一行四张卡:天气、假期、汇率、热点英语。天气大概十分钟单独刷一次,别的卡片不动。热点英语词数可配,单词上方标美式 IPA,释义和谐音默认马赛克,点一下揭开。能单词语,也能整卡连读。已会的剔掉,会补新的上来。

换电脑打开空主页会自动拉云端;空布局点同步,不会把云端已有的盖掉。壁纸、遮罩、城市在 #newtab,连 mono 仍在 #sync。

每日单词,可听读

书签和图片

书签变更会防抖上传,也能手动同步。按 Client API Key 隔离,不是全站一个池。空文件夹列表不会覆盖云端。换一把 Key,本机 New Tab、词卡、手势缓存会清掉,免得串数据。

书签

图片右键可以另存 PNG / JPG,转码在扩展里做,要 downloads 权限。

图片另存为

GitZip、V2EX、自动翻页

GitHub 公开仓库、目录、文件页可以勾选打包。单文件、目录 ZIP、多选、整仓都行。只走公开 API,不存 GitHub PAT,不接 OAuth。匿名接口有速率上限,大目录或狂点可能被限,面板会提示。选择方式和主题在 #gitzip。关掉总开关,页面注入和菜单一起停,popup 还在。

github 下载

V2EX Plus 是上游 GPLv3 模块改过来的:自动签到、未读角标、楼中楼、用户卡、sov2ex。设置字段还用 chrome.storage.sync.options,跟上游兼容。关掉就停 alarm、badge、DNR 和页面增强,工具栏点击行为不动。带这个模块一起分发,整体按 GPLv3 处理。

v2ex

AutoPagerize 滚到底会接下页。内置一大坨站点 XPath,Google / Bing 有优先覆盖,也能配排除列表。同域带 cookie 拉,跨域才走 background。HTML 解析后先去掉脚本再插入,避免宿主页跑远端代码。

自动翻页

鼠标手势

后来加的,默认关着。本机要是还开着 smartUp,两边会抢右键,只开一个就行。开了之后,普通网页按住右键划,路径收成 L / R / U / D。默认左退右进,上下刷新,右下关当前标签,上到顶,下到底。

设置页点某个动作的「绘制」,画板里按住左键划一下松手就绑上。网页上仍是右键。位移太小放行系统菜单,输入框和可编辑区域不触发。轨迹 Shadow DOM。同一路径不能绑两个动作。

映射能同步到 mono,跟 New Tab 一样按 Client API Key。「刷新」是拉,「同步」是推。空映射不会覆盖云端已有的。总开关只存在本机,不同步。chrome://、商店页、PDF 注入不进去。

代理、扩展、站点数据

代理走 chrome.proxy.settings:直连、系统代理、PAC(URL 或本地脚本)、最多五条固定服务器。默认偏系统代理,固定代理端口默认 7890。细配在 #proxy,popup 顶上能快捷切。不做账号密码认证,也没整包塞第三方代理扩展。

代理

扩展管理用 chrome.management 列出本机扩展,能搜、能开关,formant 自己不出现。完整面板在 #extensions,popup 顶栏也有二级入口。不做分组、锁定、别名那一套。

扩展管理

站点数据在 popup 里读当前 http / https 页的 Cookie、localStorage、sessionStorage。进去和切 Tab 会自动拉。能复制、单条删、整页清,都要确认。Cookie 经 background 转发。不搞跨站批量写。

storage数据

JSON Prettify 是 DevTools 面板加内容脚本查看器,接口返回直接能看。

json美化

各模块有总开关。关了停运行时,配置尽量留着。权限按能力要:alarms、bookmarks、contextMenus、cookies、downloads、management、proxy、scripting、storage 这些;GitHub、V2EX、Imgur 的 host 按需列。右键菜单按自己的 ID 增删,不 removeAll() 把别人的菜单清掉。

开关

和 mono

扩展侧就两样:环境(dev 连本地,prod 连 www.oolaf.top)和一把 Client API Key。设置页顶栏会显示 Key 指纹,不展示全文。New Tab 布局、热点英语、书签、手势映射都按这把 Key 隔离。

服务端大概是这些:formant.translate.* 翻译通道,formant.weather.* / formant.exchange.* 天气汇率,formant.vocab.model_key / card_size 热点英语,formant.newtab.default_home 默认主页。密钥只放 Admin,不进扩展仓库。

本地加载

  1. Chrome 打开 chrome://extensions,打开开发者模式

  2. 「加载已解压的扩展程序」,选中仓库里的 formant/ 目录

  3. 打开 option.html#sync,填环境和 Client API Key

  4. 到 #features 打开要用的模块,再到对应面板细调

版本号看 formant/manifest.json 的 version。要改某一块,从对应 bridge 或 option 面板顺着读就行。

下载

评论

在这里阅读读者对这篇文章的讨论。

暂无评论