自从 5 月发布了里程碑 2.0 版本后,直到差不多三个月的现在已经发布了大大小小共 14 个版本。进行了大量的改进和修复,同时也有不少新的功能。由于 Gear 的几大核心功能一直都没有详细介绍,在此公开一些内部实现的原理,以方便大家了解。
直到目前为止,Gear 依然是 iOS 首个支持油猴脚本的浏览器。有部分人认为一些浏览器支持执行 JavaScript 脚本代码就是所谓支持插件。事实上支持油猴脚本和支持 JavaScript 脚本其实是两回事。
在 iOS 上实现在页面加载前注入 JavaScript 脚本其实就是两行代码的问题。只需要调用:
let userScript = WKUserScript(source: String, injectionTime: WKUserScriptInjectionTime, forMainFrameOnly: Bool)
webView.configuration.userContentController.addUserScript(userScript)
文档:Apple Developer Documentation - WKUserScript
核心就是第一行代码,第一个参数就是要注入的 JavaScript 代码,第二个是注入的时间,可选 atDocumentStart 或 atDocumentEnd,第三个是是否只针对主 frame 执行。
就这,其实只需要几分钟的时间就能让 Web 浏览器实现执行 JavaScript 脚本(插件)的能力了。
但是,支持油猴脚本却是更加复杂的问题了。绝大部分油猴脚本都是无法通过此方式直接执行的。
首先,油猴脚本的头部注释配置定义了该脚本的执行环境、引入外部文件(如各种框架、数据、图片等)、权限授予、接口授予、以及各种相关信息。必须对此信息进行解析和保存,并在执行的时候配置好对应的代码执行环境。
还要给每个脚本配备独立的数据存储方式,不能和页面的共享。同时还要解决资源跨域访问等问题。
// ==UserScript==
// @name New Userscript
// @namespace http://tampermonkey.net/
// @version 0.1
// @description try to take over the world!
// @author You
// @match http://example.com
// @require https://cdn.staticfile.org/jquery/3.3.1/jquery.js
// @resource count https://greasyfork.org/scripts/by-site.json
// @connect translate.google.com
// @run-at document-idle
// @grant unsafeWindow
// @grant GM_addStyle
// @grant GM_getValue
// @grant GM_setValue
// ==/UserScript==
(function() {
'use strict';
// Your code here...
console.log("Hello World");
})();
以上是一个简单的油猴脚本代码。
其次,事实上目前桌面浏览器主要是这三大扩展支持执行用户脚本。而「油猴」只是其中一个的名字。
GitHub - greasemonkey/greasemonkey: Greasemonkey is a user script manager for Firefox.
GitHub - violentmonkey/violentmonkey: Violentmonkey provides userscripts support for browsers.
GitHub - Tampermonkey/tampermonkey: Tampermonkey is the most popular userscript manager.
Greasemonkey 主要对应 Firefox,而 Tampermonkey(目前最新已经不公开源代码,非开源)主要对应 Chrome 或基于 Chromium 的浏览器。它们内部都有不少地方调用了浏览器的内部接口来实现一些特殊功能。所以 Tampermonkey 也比较好移植到 Android 上。
有兴趣的,可以阅读其源代码,看看是如何实现的。
而在 iOS 上,是无法直接使用以上任何一个项目的代码来实现油猴脚本的支持。在思考了各种方案后,最终 Gear 则是选择了完全重新写一个脚本引擎来进行支持。
目前 Gear 选择的是通过 messageHandlers 来实现页面 JavaScript 与 Swift 原生代码进行数据的处理和通讯。例如跨域请求、数据存储等。并使用了缓存的方案,来加速脚本的加载和执行。原理上执行的效率会比单纯的移植高。而且还为此设计了一套 UI 交互来实现脚本的管理与安装等。于是你现在在 Gear 上可以在安装 Bilibili Evolved 这类的脚本来看 B 站,并使用各种特殊功能了……
当然,由于 Gear 的脚本引擎是完全自己开发的,并且还要同时兼顾 Greasemonkey 和 Tampermonkey 脚本的情况,所以目前还有一些接口还没有完全支持。
而且各个脚本代码的质量不一,各种奇怪的代码写法、各种代码重写、错误的引用、动不动就加载十几 MB 框架文件的情况等等,只能逐行代码来调试脚本。
目前 Gear 依然会不断对引擎进行升级来增强其兼容性。现在依然保持每隔一到两周进行一次更新,每次都会带来新的功能和实质性的改进。
如果在使用脚本过程中发现有问题,也可以直接反馈到 [email protected]。我这边会逐个进行测试和修复,尽量让其能在 Gear 运作正常。
Gear 官网:https://gear4.app
App Store: https://apps.apple.com/cn/app/gear-browser/id1458962238?ls=1