架构

本文档提供了辅助功能代码结构的高级概述。有关代码的更低级别描述,请参阅文档辅助功能生命周期页面

进程模型

辅助功能组件跨越多个进程。在父进程中,它创建 Firefox UI 的辅助功能树并响应屏幕阅读器的请求。在内容进程中,辅助功能组件从 Web 内容创建辅助功能树。

为了快速响应屏幕阅读器的请求,每个内容进程的辅助功能树都缓存在父进程中。

辅助功能树

辅助功能树可以承载不同类型的信息:非正式地,存在表示当前进程中文档的“本地树”和镜像单独进程中创建的本地树的“远程树”。

本地树只能包含当前进程中的节点,即您可以访问选项卡文档及其进程内 iframe 中的任何节点。但是,进程外 iframe 会显示为不同进程中的单独本地树。

另一方面,远程树统一了这些树:您可以访问选项卡文档及其进程内和进程外 iframe 中的任何节点。

这意味着单个选项卡有多个辅助功能树:内容进程中一个本地树,每个进程外 iframe 一个本地树,以及父进程中一个镜像这些本地树的远程树。Firefox UI 由父进程中的单个本地树表示。

树节点

辅助功能树由由 Accessible 类及其子类型表示的节点组成。以下是由 a11y::logging::Tree 打印的来自 example.com 的本地辅助功能树示例(不幸的是,没有类型信息)

A11Y TREE: Initial subtree; 44:14.388
  {
    : 0x107077a00; role: document, name: 'Example Domain', idx: 0, node: 0x105f84800, #document
      : 0x105fb8b30; role: heading, name: 'Example Domain', idx: 0, node: 0x107b048b0, h1
        : 0x105fb8c90; role: text leaf, name: 'Example Domain', idx: 0, node: 0x107b05600, #text
      : 0x105fb8d40; role: paragraph, idx: 1, node: 0x107b04940, p
        : 0x105fb8df0; role: text leaf, name: 'This domain is for use in illustrative examples in documents. You may use this domain in literature without prior coordination or asking for permission.', idx: 0, node: 0x107b05700, #text
      : 0x105fb8ea0; role: paragraph, idx: 2, node: 0x107b049d0, p
        : 0x107922030; role: link, name: 'More information...', idx: 0, node: 0x107b030e0, a [ href="https://www.iana.org/domains/example" ]
          : 0x1079220e0; role: text leaf, name: 'More information...', idx: 0, node: 0x107b05800, #text
  }

Accessible 针对不同类型的辅助功能树具有直接子类型:LocalAccessible 用于本地树的节点,RemoteAccessibleBase 用于远程树的节点。例如,LocalAccessible 可用于内容进程中的 Web 内容以及父进程中的 Firefox UI。这两种类型的后代有所不同。

LocalAccessible 的直接后代是 AccessibleWrap。按照惯例,以 Wrap 结尾的类是平台特定的实现,因此 AccessibleWrap 包含 AccessibleLocalAccessible 的平台特定实现。AccessibleWrap's 的直接和间接子类型是 HTML 和 XUL 节点的表示形式,例如 HTMLButtonAccessibleHTMLListBulletAccessible。文档和辅助功能树的根节点也由 Accessible 类表示:DocAccessibleDocAccessibleWrap 以及 RootAccessibleRootAccessibleWrap 扩展了 AccessibleWrap

RemoteAccessibleBase 没有如此广泛的类型层次结构。其主要后代是 DocAccessibleParent,它是位于父进程中的远程树的文档节点:其在内容进程中的本地树对应项是 DocAccessible

下图显示了上面描述的相同关系。在图中,实线表示直接后代,而虚线表示间接后代

flowchart TD accTitle: 上述类层次结构图 Accessible --> LocalAccessible[LocalAccessible: 本地树] & RemoteAccessibleBase[RemoteAccessibleBase: 远程树] LocalAccessible --> AccessibleWrap[AccessibleWrap: 平台特定实现] AccessibleWrap -.-> DocAccessible & HTMLButtonAccessible & HTMLListBulletAccessible DocAccessible --> DocAccessibleWrap --> RootAccessible --> RootAccessibleWrap RemoteAccessibleBase -.-> DocAccessibleParent

平台特定行为

辅助功能树因平台而异。由 LocalAccessibleRemoteAccessibleBase 等类型组成的平台无关树被编组到平台特定的树中,这使得更容易实现平台的辅助功能 API。平台树由以下节点类型组成