Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save shunf4/f574635c66b078fa447fe0c88776203e to your computer and use it in GitHub Desktop.

Select an option

Save shunf4/f574635c66b078fa447fe0c88776203e to your computer and use it in GitHub Desktop.

Screw it — at least the production artifact is editable

2026-01-19

Note

This article is AI-translated (LLM, ChatGPT 5.2) from original Chinese version (on the same page). The translation is reviewed by the author.

Today I was tweaking an open-source web auto-translation browser extension [0]. What I wanted was simple: automatically trigger translation globally on every page, and use a dedicated Profile just for browsing foreign-language sites.

Then I discovered… it doesn’t work like that. The settings let you enter an allowlist of domains to auto-trigger translation for those domains, but there’s nowhere to enable it globally. The allowlist doesn’t accept wildcards, regexes, or anything fancy either. I confirmed it in the source: the check is literally someArray.include(...). Brutal.

So I dug into the code and thought about hacking it. I wondered: could I use a UserScript, a bookmarklet, or even build another extension to trigger translation? Path one: see whether the extension exposes any public API or hook method on browser window object. As expected, no: everything is neatly encapsulated inside React.

Path two: imitate the extension’s internal messaging — send tab messages to the tab the way it does. Also a dead end. Chrome’s extension messaging is properly isolated: unless the target extension’s manifest.json explicitly allows it, a third-party extension can’t talk to it.

Path three: the extension exposes a set of “commands” meant for keyboard shortcuts, and one of them is exactly the “trigger translation” action I need. Still no way to invoke it externally. Same isolation story.

I didn’t want to pull the repo locally and build it — mental friction. And who knows what kind of build setup nonsense I’d run into.

I also didn’t want to open an issue or submit a PR. If you forced me to explain: I don’t have the patience for delayed gratification; I’m lazy; and I’m not even sure other people want this feature. Auto-triggering on every page could mess things up when you don’t want it. And if you make it too easy, you might encourage large-scale abuse of some public translation API. I didn’t want to go there.

So I decided: screw it, I’m taking the dirty route. At least the production artifact (.crx or .zip) is just modifiable JavaScript, not something more obscure.

I downloaded the Release packaged extension zip. Without even extracting it, I edited content.js inside the archive. In the sea of minified code I searched for someArray.include, and wrapped the surrounding condition with (... || true). Saved it back into the zip, then imported that zip via Chrome’s Extensions page with Developer Mode enabled.

And… it worked. The whole thing took a few minutes.

Sure, if the extension updates later I’ll need to redo the replacement. (Why would I update, anyway? I don’t need more features.) So what? This was the only approach that was both fast and guaranteed to behave exactly how I wanted. That’s probably the real meaning of editable production artifact.

[0] This extension.

去它的,至少产物代码是可修改的

2026-01-19

AI翻译的英文版在同一页面,点此

我今天在调整一个开源网页自动翻译浏览器扩展[0],希望它能全局对所有网页自动触发翻译,单独设一个Profile专门用来浏览外语网页。然后我发现……行不通,设置项可以填入域名的允许列表(allowlist),对这些域名自动触发翻译,但是没有地方可以设置成全局。允许列表也不能填通配符、正则表达式之类的东西,我在源码里确认过了,那个判断逻辑就是someArray.include(...)。真残酷。

我接着看源码,想hack它。我想到:用UserScript、bookmarklet或干脆另建一个扩展去触发翻译可以吗?第一条路——看扩展是否在浏览器window对象中留下公开可访问的API或hook方法等。如我所料没有:一切东西完美地封装在React中。第二条路——模拟扩展的内部信息传递机制,即对于tab的message——同样也行不通,Chrome对于扩展的消息机制有完善的隔离,除非扩展的清单文件(manifest.json)明确允许,第三方扩展才能与其进行消息交互。第三条路——扩展对Chrome暴露了一系列叫command的入口,专门用来实现键盘快捷键对功能的绑定,其中也包含我需要的触发翻译的行为——同样没法外部触发。同样是隔离!

我懒得拖源码到本地编译——精神上的阻尼(mental friction)迫使我不想这么干,再说了天知道设定项目构建又会出什么幺蛾子。我也不想提issue和拉取请求——硬要我解释我会说我没有延迟满足的耐心,我懒,并且我不确定其他人真会想要这样的特性吗?——自动对所有网页触发一个可能并不想要的动作,有可能把网页弄乱?——并且允许了这玩意可能会促进对公开的翻译API造成大规模滥用。我不想走这条路。

最后我决定:去它的,我走脏路子了。至少构建产物是可以修改的JavaScript,不是什么更隐晦的东西。于是我下载了Release的已打包扩展zip文件,没有解压直接编辑content.js文件,在一大堆的minified代码中搜索someArray.include然后在这个条件周围包裹上(... || true),保存到压缩文件中,然后将压缩文件导入开启了开发者模式的Chrome扩展管理器。然后……这一切就工作了,整个过程只花了几分钟。

我清楚如果扩展之后有更新的话我需要重复这种替换(我为什么要更新呢?我又不需要更多新功能),但是又怎样呢?至少这是又快又能让事情如我预期工作的唯一方法。这大概就是产物代码可修改的意义吧。

[0] 这个扩展

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment