如何通过快捷键或命令打开Safari Web Extension弹窗?
如何通过快捷键打开Safari Web Extension的弹窗
针对Safari Web Extension(非App Extension),确实没有内置的快捷键打开弹窗的机制,但可以通过Web脚本+原生扩展Handler的组合实现,以下是完整的实现步骤:
1. 完善Content脚本(监听快捷键)
修改content.js,设置精准的快捷键组合(避免和网页/浏览器默认快捷键冲突):
document.addEventListener('keydown', function(event) { // 示例:监听 Ctrl+Shift+O 组合键 if (event.ctrlKey && event.shiftKey && event.key === 'O') { event.preventDefault(); // 阻止默认行为,避免干扰 browser.runtime.sendMessage({ action: "triggerPopover" }).then((response) => { console.log("弹窗打开响应: ", response); }); } });
2. 调整Background脚本(转发消息到原生)
更新background.js,将消息封装为对象,方便原生端解析:
browser.runtime.onMessage.addListener((request, sender, sendResponse) => { if (request.action === "triggerPopover") { browser.runtime.sendNativeMessage( "com.owner.MyExtension", // 需与原生扩展的Bundle Identifier一致 { command: "openPopover" } ).then((response) => { sendResponse({ status: "success", msg: response.echo }); }).catch((error) => { console.error("发送原生消息失败: ", error); sendResponse({ status: "error", msg: error.message }); }); } return true; // 保持端口开放,等待异步响应 });
3. 实现原生Handler(打开弹窗)
补全SafariWebExtensionHandler.swift,通过Safari原生API触发弹窗:
import SafariServices class SafariWebExtensionHandler: NSObject, NSExtensionRequestHandling { func beginRequest(with context: NSExtensionContext) { // 解析来自Web扩展的消息 guard let inputItem = context.inputItems.first as? NSExtensionItem, let messageDict = inputItem.userInfo?[SFExtensionMessageKey] as? [String: Any], let command = messageDict["command"] as? String, command == "openPopover" else { context.completeRequest(returningItems: nil, completionHandler: nil) return } // 获取当前活跃的Safari窗口、标签页,触发弹窗 SFSafariApplication.getActiveWindow { window in window?.getActiveTab { tab in tab?.getToolbarItem { toolbarItem in toolbarItem?.showPopover { error in let responseItem = NSExtensionItem() var responseDict = [String: Any]() if let error = error { responseDict["echo"] = "打开弹窗失败: \(error.localizedDescription)" } else { responseDict["echo"] = "弹窗已打开" } responseItem.userInfo = [SFExtensionMessageKey: responseDict] context.completeRequest(returningItems: [responseItem], completionHandler: nil) } } } } } }
关键注意事项
- Bundle Identifier一致性:
background.js中sendNativeMessage的第一个参数必须和Xcode中原生扩展目标的Bundle Identifier完全一致(比如com.owner.MyExtension)。 - 权限与启用:确保在Safari偏好设置→扩展中启用你的Web Extension,并赋予必要的网站访问权限。
- Xcode配置:在原生扩展的
Info.plist中,确认NSExtensionPrincipalClass的值指向SafariWebExtensionHandler(格式为$(PRODUCT_MODULE_NAME).SafariWebExtensionHandler)。
内容的提问来源于stack exchange,提问作者Alonso Huerta
相关产品推荐
相关产品推荐

