给网页应用注入 CSS 和 JavaScript
Pake CLI 的 --inject 可以接一个或多个本地 .css 或 .js 文件,构建时打进应用,之后应用打开的每个页面都会带上它们;桌面版在高级里对应的是注入 CSS 和注入 JavaScript 两栏。隐藏横幅、调大字号用 CSS 最稳,JavaScript 能做的事更多但也坏得更快,另外只注入自己写的或者逐行读过的代码。
--inject 能接什么
CLI 文档对 --inject 的描述是,把本地的 CSS 和 JS 文件(绝对路径或相对路径都行)注入到你指定的网址对应的页面里,两种写法都支持,也可以混用:
# 逗号分隔
pake https://example.com --name Example --inject ./tools/style.css,./tools/hotkey.js
# 重复写选项
pake https://example.com --name Example --inject ./tools/style.css --inject ./tools/hotkey.js
每个文件必须以 .css 或 .js 结尾。源码里只要列表里混进别的后缀,就会输出 "The injected file must be in either CSS or JS format." 然后停止注入,所以样式没生效时先看构建输出。相对路径是按你运行 pake 的目录解析的,不是按列出它们的那个文件所在的目录。
文件是在构建时读取并复制进应用的,所以应用建好之后再改 style.css 不会有任何变化,需要用同一条命令重新构建。如果你把选项放在 JSON 配置文件里,inject 也是字符串数组,其余参数见 CLI 选项。
CSS 适合做什么
CSS 只改外观,所以应该先试它。常见的活儿是隐藏推广横幅、Cookie 提示条或者你从不用的侧栏,把基础字号调大,或者把过宽的正文栏收窄一点:
.promo-banner { display: none !important; }
body { font-size: 17px !important; }
选择器先在浏览器里找:打开网站,检查元素,复制一个看起来稳定的类名或属性,比如 [data-testid="sidebar"] 就比 .css-1x9k2f 这种生成出来的类名可靠,因为后者每次站点部署都可能变。网站经常用很具体的选择器设置属性,所以在你要改的那一条属性上加 !important 很正常。
只是缩放的话可能根本不用写代码,每个 Pake 应用都有缩放快捷键,见快捷键参考,不碰页面的原生选项在窗口定制里讲。
JavaScript 容易出什么问题
JavaScript 可以点击、删除、改写元素,也能加快捷键,但它依赖页面结构,而页面是别人的。常见的失败有这几种:
- 网站改了页面结构。 用
querySelector找按钮的脚本,会在按钮换了类名的那天失效,而且是悄悄失效,你只会发现效果没了。 - 元素出现得晚。 现代网站加载后才渲染,脚本要找的元素可能还不存在,应该监听 DOM 变化或重试,不要只检查一次。
- 代码在每个页面都跑。 同一段脚本会在登录页和设置页运行,用
location.hostname或location.pathname先判断一下。 - 页面自己的策略挡路。 网站可以用内容安全策略限制内联样式和脚本。样式这一侧 Pake 做了处理:页面挡掉
<style>元素时,注入器会退到可构造样式表,不过含@import的 CSS 仍然受页面策略约束;脚本能否运行仍要单独测试,不能从样式的回退结果推断。
脚本尽量短、写得保守,CSS 能解决的就别用 JavaScript。
Pake 是怎么注入的
传入 --inject 后,CLI 把每个文件包一层,按你写的顺序拼接,写进构建目录里的 src-tauri/src/inject/custom.js。CSS 文件会变成一个 DOMContentLoaded 监听器,把你的 CSS 当字符串交给 window.__PAKE_INJECT_STYLE__,它往文档里追加一个 <style> 元素。JS 文件则原样放进它自己的 DOMContentLoaded 监听器里,收尾的大括号单独占一行,这样文件末尾是 // 注释也不会把包装弄坏。
运行时 Pake 会给 web view 注册一串初始化脚本,除去几个只在特定选项下才加载的脚本,窗口代码里的顺序依次是 Pake 配置、链接和登录处理、样式助手、提示助手、事件脚本、Pake 自己的样式脚本和主题刷新,最后才是 custom.js。所以你的代码在 Pake 之后运行,此时页面 DOM 已经就绪,你的 CSS 在层叠里也排在 Pake 自己的规则后面。内置的 style.js 里有一些按站点生效的小修补,只在对应域名上起作用,所以你打包的网站不会吃到为别的站点写的规则。
文件是编译进去的,等于应用的一部分,把构建产物拷到另一台电脑上,注入的代码也跟着走;桌面版的设置文件迁移见迁移网页应用。
调试注入的内容
构建时加 --debug,文档里说明它会启用开发者工具和详细日志:
pake https://example.com --name Example --inject ./style.css --debug
调试构建里可以切换开发者工具,Mac 上是 Cmd Option I,Windows 和 Linux 上是 Ctrl Shift I,快捷键表里标明只在调试版可用。打开后在 Elements 里看有没有 <style> 元素或者你的规则,在 Console 里看脚本报错,选择器在这里改到能用,再抄回文件重新构建。正式构建不带这个开关,别指望在发出去的应用里打开它。
桌面版对应的位置
Pake 桌面版(Mac 和 Windows)的高级里有注入 CSS 和注入 JavaScript,是你自己的样式和脚本,作用于应用打开的每个页面。在我的应用里点编辑,粘贴代码,点保存修改,编辑会原地重装同一个应用。某段样式把页面搞坏了,就清空那一栏再保存一次。
设置文件也会带上这些代码,但导入的 CSS 和 JavaScript 默认是关的,要在高级里读完再点使用导入的代码,原因是别人给的文件里什么都可能有。
只运行检查过的代码
注入的脚本在你打包的网站页面里运行,能接触到你在那个站点登录后的一切。网上找来的脚本可能读走消息或者把数据发到别处,界面上看不出任何迹象,所以共享来的文件要逐行读过再用,脚本也尽量只针对一个站点。Pake 文档说明它的原生桥只对配置的那个网站来源开放,这限制了页面能向应用要什么,但页面本身仍然可以被你注入的代码随意操控。
常见问题
能注入远程 URL 吗?
不能,CLI 在构建时从磁盘读取每个路径,所以先下载下来读一遍,再传本地路径。
文件顺序有影响吗?
有,它们按你列的顺序拼接,规则冲突时后面的 CSS 覆盖前面的。
改了 CSS 要重新构建吗?
CLI 要,因为文件是编译进去的;桌面版改完那一栏点保存修改,应用会带着新代码原地重装。
