通过MACOS可访问性API在WebKit应用程序中选择文本

发布于 2025-02-04 07:23:56 字数 808 浏览 1 评论 0原文

我需要使用可访问性API在另一个应用程序(Apple Mail)的WebKit视图中选择文本。

对于常规文本字段,我会执行类似的操作:

func selectText(withRange range: CFRange) throws {
    var range = range
    guard let newValue: AXValue = AXValueCreate(AXValueType.cfRange, &range) else { return }
    AXUIElementSetAttributeValue(self, kAXSelectedTextRangeAttribute as CFString, newValue)
}

但是,在Apple Mail的编写窗口中,每个文本似乎都是类型静态文本,它不带任何必要的axselectedtextrange

它具有axselectedTextmarkErnange,它需要axtextmarker。我只是没有如何创建其中之一。我毫不费力地阅读用户创建选择的文本,使用此在这里/a>,但我无法通过可访问性API选择文本。

I need to select text in a WebKit view of another application (Apple Mail) using accessibility APIs.

For regular text fields, I do something like this:

func selectText(withRange range: CFRange) throws {
    var range = range
    guard let newValue: AXValue = AXValueCreate(AXValueType.cfRange, &range) else { return }
    AXUIElementSetAttributeValue(self, kAXSelectedTextRangeAttribute as CFString, newValue)
}

However, in the composing window of Apple Mail every text seems to be of type Static Text which doesn't come with the necessary AXSelectedTextRange

It has AXSelectedTextMarkerRange, though, which requires an AXTextMarker. I just don't get how to create one of these. I have no trouble reading the text from a user created selection using this here, but I'm unable to select text via the accessibility APIs.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

太阳男子 2025-02-11 07:23:56

感谢 willeke 我能够弄清楚的提示。确实可以使用axtextmarkerforindex进行操作。知道它实际上很简单。

这是我的代码:

func getTextMarker(forIndex index: CFIndex) throws -> AXTextMarker? {
        var textMarker: AnyObject?
        guard AXUIElementCopyParameterizedAttributeValue(self,"AXTextMarkerForIndex" as CFString, index as AnyObject, &textMarker) == .success else { return nil }
        return textMarker as! AXTextMarker
}

func selectStaticText(withRange range: CFRange) throws {
        guard let textMarkerStart = try? getTextMarker(forIndex: range.location) else { return }
        guard let textMarkerEnd = try? getTextMarker(forIndex: range.location + range.length) else { return }
        let textMarkerRange = AXTextMarkerRangeCreate(kCFAllocatorDefault, textMarkerStart, textMarkerEnd)

        AXUIElementSetAttributeValue(self, "AXSelectedTextMarkerRange" as CFString, textMarkerRange)
}

Thanks to the hint from Willeke I was able to figure it out. It is indeed possible to do it using AXTextMarkerForIndex. Knowing that it's actually pretty straightforward.

Here's my code:

func getTextMarker(forIndex index: CFIndex) throws -> AXTextMarker? {
        var textMarker: AnyObject?
        guard AXUIElementCopyParameterizedAttributeValue(self,"AXTextMarkerForIndex" as CFString, index as AnyObject, &textMarker) == .success else { return nil }
        return textMarker as! AXTextMarker
}

func selectStaticText(withRange range: CFRange) throws {
        guard let textMarkerStart = try? getTextMarker(forIndex: range.location) else { return }
        guard let textMarkerEnd = try? getTextMarker(forIndex: range.location + range.length) else { return }
        let textMarkerRange = AXTextMarkerRangeCreate(kCFAllocatorDefault, textMarkerStart, textMarkerEnd)

        AXUIElementSetAttributeValue(self, "AXSelectedTextMarkerRange" as CFString, textMarkerRange)
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文