我有目前在 Chrome、Firefox 和 Opera 上运行的 Web 扩展。现在我想知道是否有一种方法可以使用相同的代码来构建 Safari 应用程序扩展,可能类似于 PhoneGap(将所有现有的 JS 代码包装在 Safari 应用程序扩展项目中),或者有一些限制,比如 javascript 的标签处理和一些事情只需要用本机代码编写。
谢谢
我有目前在 Chrome、Firefox 和 Opera 上运行的 Web 扩展。现在我想知道是否有一种方法可以使用相同的代码来构建 Safari 应用程序扩展,可能类似于 PhoneGap(将所有现有的 JS 代码包装在 Safari 应用程序扩展项目中),或者有一些限制,比如 javascript 的标签处理和一些事情只需要用本机代码编写。
谢谢
您应该能够重用 Web 扩展中的内容脚本(但您需要重写代码才能发送/接收带有“背景”的消息)。后台脚本必须用 Swift 或 Objective-C 重写。
你需要开发:
您在 Apple 网站上有一个(小)示例:https ://developer.apple.com/documentation/safariservices/safari_app_extensions?changes=_2&language=objc
您不应再使用 Extension Builder(可从 Safari 的开发人员菜单访问),因为这仅适用于旧版(纯 JS)扩展。所以你需要进入 XCode。
最后一件事,但并非最不重要的... Safari App Extensions 与 Safari 旧版扩展相比,“有点”受到更多限制(例如,您将无法以编程方式打开工具栏弹出窗口,就像 Chrome 网络扩展一样实际上)。
现在有官方支持这种转换:
分享我的发现可能为时已晚,但尽管如此。
将 web 扩展转换为 safari 应用扩展的可能性的 简短回答是Yes。绝对有可能,但很难做到。
我很难找出将 Web 扩展移植到 safari 应用程序扩展的最佳和最小方法。
移植 Web 扩展的问题
解决方案
编写一些 swift/objective-c 代码是不可避免的。但是用 swift/objective C 编写桥接代码以促进内容脚本和后台脚本之间的通信使生活更轻松。
在图中,Content-script 保持不变,背景脚本是通过创建 webview 来注入的。现在从内容脚本收到的任何消息都转发到 webView 后台脚本。还使用设置浏览器扩展 APIevaluvateJavascript
webView.evaluateJavaScript("chrome.runtime.id=function() { return "+ extensionId + " }")
Electron JS 使用简单的 HTML、CSS 和 JavaScript 等 Web 技术。除非您想做一些高级的事情,否则它不需要本机技能。它可以设计用于单个浏览器。它的文件系统属于 Node.js API,适用于 Linux、Mac OS X、Windows。
通过使用本机节点模块,您可以使用 C++ 和 ObjectiveC(或 Swift)编写并使用 v8 向 node.js 公开 API。这为您提供了很大的灵活性和功能,但需要最多的时间来开发,并且仍然通过在电子上下文中运行来重用您的后台脚本。
使用这种方法构建的示例应用程序 https://github.com/AdguardTeam/AdGuardForSafari
如果您想在 Safari 应用程序扩展中进行窗口/选项卡管理,请参阅WindowTabManagement
更新
如果您打算使用零本机代码 (Objective-c/swift) 移植旧版扩展。请关注此回购 https://github.com/avast/topee
你实际上可以很容易地做到这一点。
如果我们谈论的是 Safari 应用程序扩展而不是旧版 Safari 扩展(在 Safari v12 中已弃用),那么我的理解是需要快速重写后台脚本。关于内容脚本,它们仍在 JS 中,但所有使用 chrome API 调用编写的消息都必须使用 Safari 应用程序 API 重写。
如上所述,内容脚本可以与您在 Firefox 和 Chrome 扩展程序中创建的捆绑包保持相同。您只需将其包含在您的 plist 中。为了避免重写 Swift 中的所有后台逻辑,我使用了一个名为JavascriptCore
Apple 提供的库。这允许您创建一个 JavaScript 上下文并将数据从 Swift 后台传递到您的 JavaScript 后台包。
例如:safariExtensionHandler.swift
有一个名为messageReceived
. 此函数可以使用 Swift 从 Swift 调用代码中的全局 JavaScript 函数JavascriptCore
。
您可以参考此链接了解如何将 Google Chrome 扩展程序转换为 Firefox 或 Safari 扩展程序。
目前有一些手工工作要做。
https://github.com/kritollm/chrome-extension-api-for-safari-and-firefox
在我第一次写这篇文章之后,我知道了另外两个非常相似的项目。
https://code.google.com/p/adblockforchrome/source/browse/trunk/port.js 和
此外,这里是如何使用 WebExtensions 将 Chrome 扩展转换为 Firefox 插件的官方指南。
并非所有东西都可以用 Swift 编写。例如,我尝试从 extensionHandler 调用 dylib,但失败了。