1

我正在将扩展从 Chrome/Firefox 移植到 iOS 上的 Safari。当扩展弹出窗口出现时,iOS 上的 Safari 上有两种不同的行为。在 iPhone 上,它从屏幕底部以全屏宽度菜单的形式出现。在 iPad 上,它的行为与 MacOS 上的 Safari 类似,并且弹出窗口从工具栏中的扩展图标下来,并且是动态大小的。

我想在我的 javascript 代码中检测这两种不同的情况。在前一种情况下,我想避免设置弹出窗口的宽度(因为这会导致问题),在后一种情况下,我确实想设置宽度(就像我在 Chrome 等中所做的那样)。

我不确定这是否是检测 iPad 与 iPhone 的情况(但我有兴趣知道如何做到这一点)。可能有一个屏幕尺寸足够大的 iPhone 会导致它使用后一种行为。

4

1 回答 1

1

虽然通过使用来确定 macOS 与 iOS 相当简单browser.runtime.getPlatformInfo(),但确定 iOS 与 iPadOS 则更加困难。

当扩展弹出窗口出现时,iOS 上的 Safari 上有两种不同的行为。在 iPhone 上,它从屏幕底部以全屏宽度菜单的形式出现。在 iPad 上,它的行为与 MacOS 上的 Safari 类似,并且弹出窗口从工具栏中的扩展图标下来,并且是动态大小的。

请记住,在 iPadOS上,当浏览器处于拆分视图时,弹出窗口也可以像在 iOS 上一样显示因此,跟踪窗口调整大小事件并在所有拆分视图大小中测试弹出窗口进出拆分视图非常重要。

我发现的唯一完整的解决方案是结合使用 Swift、Javascript 和 CSS。

迅捷的一面

在您的 WebExtension 或任何您喜欢的地方,您可以创建一个简单的函数来返回您所在的平台。我使用了这个,browser.runtime.getPlatformInfo()因为后者无法区分 iOS 和 iPadOS。就像是:

func getPlatform() -> String {
    var platform:String
    #if os(iOS)
        if UIDevice.current.userInterfaceIdiom == .pad {
            platform = "ipados"
        }
        else {
            platform = "ios"
        }
    #elseif os(macOS)
        platform = "macos"
    #endif
    return platform
}

为了与应用程序的 swift 端进行通信,您需要使用javascript 端的本机消息传递- 并将适当的消息处理程序放在您的 swift 端。

背景.js


browser.runtime.sendNativeMessage({name: "getPlatformFromSwiftSide"}, response => {
    if (response.platform === "ipados") {
        ...
    } else if (response.platform === "ios") {
        ...
    }
});

SafariWebExtensionHandler.swift

class SafariWebExtensionHandler: NSObject, NSExtensionRequestHandling {
    func beginRequest(with context: NSExtensionContext) {
        let item = context.inputItems[0] as? NSExtensionItem
        let message = item?.userInfo?[SFExtensionMessageKey] as? [String: Any]
        guard let name = message?["name"] as? String else {return}
        let response = NSExtensionItem()
        if name == "getPlatformFromSwiftSide" {
            let platform = getPlatform()
            response.userInfo = [SFExtensionMessageKey: ["platform": platform]]
        }
        context.completeRequest(returningItems: [response], completionHandler: nil)
    }
}


此时你可以区分 iPadOS 和 iOS 了。但是,您仍然存在浏览器是否处于拆分视图中的问题。如前所述,对于拆分视图中的某些尺寸,iPadOS 上的弹出窗口布局不同,您必须考虑到这一点。

matchMedia目前,除了 CSS 媒体查询或 Javascript调用之外,我不知道有任何方法可以轻松确定这一点。

此外,从弹出窗口调用window(或在弹出窗口上下文中使用媒体查询)不会指示浏览器的大小,而是指示弹出窗口。由于我们不知道浏览器大小来确定如何调整弹出窗口的大小,因此我知道完成此操作的唯一可靠方法是使用browser.tabs.sendMessage, 向内容脚本发送一条请求浏览器window大小的消息。


所有这一切似乎都比它需要的复杂,但我目前不知道其他选择。

于 2021-12-29T14:50:34.803 回答