将 Web 扩展转换为 Safari 应用扩展

Convert Web Extension to Safari App Extension

我有当前在 Chrome、Firefox 和 Opera 上运行的 Web 扩展。 现在我想知道是否有一种方法可以使用相同的代码来构建 Safari App Extension,可能是像 PhoneGap(将所有现有的 JS 代码包装在 Safari App Extension 项目中)或者有一些限制,比如 javascript 的选项卡处理和一些事情只需要用本机代码编写。

谢谢

您可以参考此 link 如何将 Google Chrome 扩展转换为 Firefox 或 Safari 扩展。

There is currently a bit of manual work to be done.

https://github.com/kritollm/chrome-extension-api-for-safari-and-firefox

After I first wrote this post, I have been aware of two other projects which are very similar.

https://code.google.com/p/adblockforchrome/source/browse/trunk/port.js and

https://github.com/jetpack-labs/chrome-tailor-jetpack

此外,这里是 official guide 如何使用 WebExtensions 将 Chrome 扩展转换为 Firefox 附加组件。

如果我们谈论的是 Safari 应用程序扩展而不是旧版 safari 扩展(在 Safari v12 中已弃用),那么我的理解是后台脚本需要在 swift 中重写。 关于内容脚本,它们仍在 JS 中,但所有使用 chrome API 调用编写的消息必须使用 Safari 应用程序 APIs.

重写

您应该能够重用 Web 扩展中的内容脚本(但您需要重写代码才能 send/receive 消息与 "background")。 必须在 Swift 或 Objective-C.

中重新编写后台脚本

你需要开发p:

  • a Mac 主机应用程序(将与扩展配套):Swift 或 Objective-C(此应用程序必须具有通过 Apple 审查的最低功能 - 检查 Apple Mac 应用指南)
  • 扩展名:在 Swift 或 Objective-C + HTML/JS(对于其他浏览器) Swift(或 Obj-C)中用于扩展的代码等同于您在 Web 扩展中拥有的背景页面。它将控制工具栏按钮、扩展的生命周期并且可以与注入的脚本对话。

A​​pple 网站上有一个(小)示例:https://developer.apple.com/documentation/safariservices/safari_app_extensions?changes=_2&language=objc

您不应再使用扩展生成器(可从 Safari 中的“开发人员”菜单访问),因为它仅适用于遗留(纯 JS)扩展。所以你需要进入 XCode.

最后但同样重要的是...与 Safari 遗留扩展相比,Safari 应用程序扩展 "a bit" 更受限制(例如,您将无法以编程方式打开工具栏弹出窗口,只是实际上与 Chrome 网络扩展一样)。

并不是所有的东西都可以写成Swift。例如,我尝试从 extensionHandler 调用 dylib,但失败了。

如上所述,内容脚本可以与您在 Firefox 和 Chrome 扩展程序中创建的包相同。你只需要将它包含在你的 plist 中。 为了避免重写Swift中的所有后台逻辑,我使用了Apple提供的名为JavascriptCore的库。这允许您创建一个 JavaScript 上下文并将数据从 Swift 后台传递到您的 JavaScript 后台包。

例如:safariExtensionHandler.swift 有一个名为 messageReceived 的函数。此函数可以使用 JavascriptCore.

从 Swift 调用代码中的全局 JavaScript 函数

现在分享我的发现可能为时已晚,但尽管如此。

将 Web 扩展转换为 Safari 应用程序扩展的可能性的简短回答是 。绝对有可能,但很难做到。

我很难找出将 Web 扩展移植到 safari 的最佳和最小方法 app-extension。

移植 Web 扩展时出现问题

  1. Safari App-Extension 不提供 API tab/window 管理。 (即添加、删除或更新选项卡或 window 时,windows 和选项卡的唯一标识符)
  2. 需要一些关于 swift/objective -c 的学习或经验才能实现后台功能。
  3. 调试成为开发过程中的痛点。

解决方案

编写一些 swift/objective-c 代码是不可避免的。但是在 swift/objective C 中编写一个桥接代码以方便 content-script 和 background-script 之间的通信使生活更容易。

  • 使用桥接代码的方法 1 Architectural Design

图中,Content-script保持不变,background-script通过创建webview注入。现在从 content-script 收到的任何消息都会转发到 webView background-script。同时使用 evaluvateJavascript

设置浏览器扩展 API
webView.evaluateJavaScript("chrome.runtime.id=function() { return "+ extensionId + " }")
  • 方法 2:使用 Electron 驱动的浏览器扩展

Electron JS 使用简单的 HTML、CSS 和 JavaScript 等网络技术。除非您想做一些高级的事情,否则它不需要本地技能。它可以为单个浏览器设计。它的文件系统属于 Node.js APIs 并且工作在 Linux, Mac OS X, Windows.

通过使用 native node modules,您可以使用 C++ 和 ObjectiveC(或 Swift)编写,并使用 v8 公开 API 到 node.js。这为您提供了很大的灵活性和功能,但需要最多的时间来开发并且仍然要在电子上下文中由 运行 重用您 background-script。

使用此方法构建的示例应用程序 https://github.com/AdguardTeam/AdGuardForSafari

如果你想在 safari 应用程序扩展中做 Window/Tab 管理参考 WindowTabManagement

更新

如果您计划使用零本机代码移植旧版扩展 (Objective-c/swift)。请关注此回购 https://github.com/avast/topee

现在正式支持这种转换:

Converting a Web Extension for Safari

实际上你可以很容易地做到这一点。

  • 请记住,您需要 Xcode v.12 和 Safari 12 才能正常工作。
  1. 从 chrome 商店下载 .crx 文件。
    1. 我用过这个:https://crxextractor.com
  2. 用终端解压«unzip»。
  3. 从终端类型 xc运行 safari-web-extension-converter /path/to/manifest/ 和 运行 输入 当被问及是否 swift 时。这应该打开 Xcode.
  4. 来自 Xcode - 编译和 运行。
  5. 现在激活它:
    1. 转到 safari,首选项,启用开发模式。
    2. 然后转到新的“开发”选项卡 - 在书签旁边。
    3. «允许未签名的扩展»
  6. 然后转到首选项和扩展程序,您应该会看到您的扩展程序。