Firefox OS TV 的键盘事件

入门

在 Firefox OS 中,通过硬件按键输入事件的行为在不同的应用程序之间存在很大差异。早期的智能手机只配备了少量按键——电源、主页、音量加、音量减——因此软件很容易为每个按键事件确定适当的响应。但是,现在的智能电视遥控器配备了多种硬件按键,在按下按键时定义适当的行为已成为 Firefox OS TV 平台上的一个重要问题。如果智能遥控器上的硬件按键可以同时由应用程序和系统使用,那么确定按下按键时触发哪个响应就非常重要。

本文将介绍在 Firefox OS 智能电视平台上,对电视遥控器进行编程以管理键盘事件所面临的挑战。我们将把键盘事件划分为四种场景,并描述这些派发场景以及它们的交互方式。这是关于 Firefox OS 智能电视键盘事件的两篇文章中的第一篇。在后续的 第二篇文章 中,我们将深入研究实现细节,并查看在电视遥控器上进行事件处理的示例代码。

f1

[图 1]

我们从电视遥控器上的“信息”按键开始。通常,硬件使用它来显示系统信息,虽然应用程序可以使用同一个按键来显示应用程序信息。当用户按下此按键时,屏幕上将显示哪个操作——系统信息还是应用程序信息?

四种键盘事件场景

为了确定按下硬件按键时的适当行为,我们首先描述键盘事件的四种场景。

场景 描述 事件顺序
SYSTEM-ONLY 仅供 mozbrowser-iframe-host-page 处理的按键。 system
SYSTEM-FIRST 可以先由 mozbrowser-iframe-host-page 处理,然后也可以由 mozbrowser-iframe-embedded-page 处理的按键。 system->app
APP-CANCELLED 仅供 mozbrowser-iframe-embedded-page 处理的按键。 app
APP-FIRST 可以先由 mozbrowser-iframe-embedded-page 处理,然后也可以由 mozbrowser-iframe-host-page 处理的按键。 app->system

[表 1]

[Fig 2]

[图 2]

表 1 中提到的 mozbrowser-iframe-host-pagemozbrowser-iframe-embedded-page 在上面的图 2 中进行了说明。如果 A.html 代表一个源代码为 B.html 的主机页面,那么 A.html 就是 mozbrowser-iframe-host-page,B.html 就是 mozbrowser-iframe-embedded-pagemozbrowser 使用非标准的 Firefox 浏览器 API,它专为在 Firefox OS 应用程序中实现关键功能和内容体验而构建。了解更多关于 MDN 上的 mozbrowser 的信息。

任何给定键盘事件的适当响应取决于场景。在上面说明的例子中,假设“信息”键盘事件被归类为 APP-FIRST,并且系统设置的默认操作是显示系统信息。因此,当我们在应用程序 Z 处于前台的情况下按下“信息”键时,会有两种可能的结果

    1. 如果应用程序 Z 有一个事件处理程序,指示“信息”键显示应用程序信息,那么当用户按下遥控器上的“信息”键时,将显示应用程序信息。
    2. 如果应用程序 Z 没有为“信息”键设置事件处理程序,则将触发默认操作。也就是说,屏幕将显示系统信息。

如何实现四种场景

为了实现上面描述的四种键盘事件场景,我们引入了四个新的键盘事件

      • mozbrowserbeforekeydown – 在 keydown 事件 之前 触发
      • mozbrowserafterkeydown – 在 keydown 事件 之后 触发
      • mozbrowserbeforekeyup – 在 keyup 事件 之前 触发
      • mozbrowserafterkeyup – 在 keyup 事件 之后 触发

这四个键盘事件只会被嵌入 mozbrowser-iframe 的 window 接收。

键盘事件按照特定的时间顺序发生:mozbrowserbeforekeydownmozbrowserafterkeydownmozbrowserbeforekeyupkeyupmozbrowserafterkeyup

这为开发者提供了一种方法来实现上面提到的四种场景。从概念上讲,可以分别通过为 mozbrowserbeforekey*mozbrowserafterkey* 事件设置适当的处理程序来实现 SYSTEM-ONLY、SYSTEM-FIRST 和 APP-CANCELLED、APP-FIRST 场景。SYSTEM-ONLY 和 SYSTEM-FIRST 场景可以通过为 mozbrowserbeforekey* 事件设置适当的处理程序来实现,而 APP-CANCELLED 和 APP-FIRST 场景则可以通过 mozbrowserafterkey* 事件来实现。

Firefox OS 中的 iframe 结构

[Fig 3]

[图 3]

为了理解如何实现这四种场景,让我们首先看一下 Firefox OS 中的 iframe 结构。Firefox OS 中最外层的 iframe 是 shell.html。它嵌入了一个来自 system/index.html进程内 iframe。系统应用程序 (system/index.html) 包含多个 Web 应用程序(本质上是 iframe),它们可以是 进程内 (remote=”false”) 或 进程外 (remote=”true”)。因此,这三层之间的关系可以用下表表示

mozbrowser iframe 主机页面 mozbrowser iframe 嵌入页面
shell.html system/index.html
system/index.html Web 应用程序(本质上是 iframe)

[表 2]

键盘事件的派发顺序

[Fig 4]

[图 4]

当一个 keydown 事件被发送到 mozbrowser-iframe-embedded-page 中的某个元素时,嵌入 iframe 的所有者,即 mozbrowser-iframe-host-page,将在 keydown 事件发送之前收到 mozbrowserbeforekeydown 事件,并在事件发送到 mozbrowser-iframe-embedded-page 之后收到 mozbrowserafterkeydown 事件。

在 Gecko 中,一旦有一个目标在 HTML 文档中嵌入的进程外 iframe 中的 keydown 事件,keydown 事件就会复制到 HTML 文档中。此复制事件的目标被设置为嵌入的 iframe 元素。

这导致了图 4 中所示的键盘事件序列。它说明了当需要派发目标在 mozbrowser-iframe-embedded-page 中的 keydown 事件时,所有相关的 keydown 事件及其关系。简而言之,事件按照以下顺序执行

      1. 在派发任何 keydown 事件之前,mozbrowserbeforekeydown 事件首先派发到 mozbrowser-iframe-host-page 的窗口。
      2. 然后,原始的 keydown 事件(目标在 mozbrowser-iframe-embedded-page 中)将被复制到 mozbrowser-iframe-host-page HTML 文档中。它的目标将被设置为包含 mozbrowser-iframe-embedded-page 的 iframe。
      3. 接下来,原始的 keydown 事件将被派发到它的目标。
      4. 在原始的 keydown 事件派发完成后,mozbrowserafterkeydown 事件将被派发到 mozbrowser-iframe-host-page 的窗口。

请注意,上面描述的事件派发过程遵循 DOM 树事件流。事件序列和事件目标可以整理到下表中

顺序 事件 目标
1 mozbrowserbeforekeydown mozbrowser-iframe-host-page 中的窗口
2 keydown mozbrowser-iframe-host-page 中包含 mozbrowser-iframe-embedded-page 的 iframe
3 keydown mozbrowser-iframe-embedded-page 中的原始事件
4 mozbrowserafterkeydown mozbrowser-iframe-host-page 中的窗口

[表 3]

f5

[图 5]

键盘事件 mozbrowserbeforekeydownkeydownmozbrowserafterkeydown 可以扩展到嵌套的 mozbrowser iframe,例如表 2 中描述的 Firefox OS 中的 iframe 结构。在这种情况下,mozbrowserbeforekeydownmozbrowserafterkeydown 事件将被派发到最里面的 mozbrowser-iframe-host-page 以及最外面的那个。因此,在 Firefox OS 中,mozbrowserkeydownmozbrowserafterkeydown 将被派发到 system/index.html 的窗口和 shell.html 的窗口。图 5 说明了当一个 keydown 事件被派发到一个 Web 应用程序时,所有相关事件的整个派发顺序。事件顺序在表 4 中进行了演示。

顺序 事件 目标
1 mozbrowserbeforekeydown shell.html 中的窗口
2 mozbrowserbeforekeydown system/index.html 中的窗口
3 keydown system/index.html 中包含 Web 应用程序的 iframe
4 keydown Web 应用程序中的原始事件
5 mozbrowserafterkeydown system/index.html 中的窗口
6 mozbrowserafterkeydown shell.html 中的窗口

[表 4]

f6

[图 6]

虽然 keyup 事件必须在 keydown 事件之后触发,但 keydown 事件和 keyup 事件是相互独立的。此外,路径 mozbrowserbeforekeyupkeyupmozbrowserafterkeyup 与路径 mozbrowserbeforekeydownkeydownmozbrowserafterkeydown 是相互独立的。因此,这两个路径可能交叉。mozbrowserbeforekeyup 可能会在 keydown 事件之前到达。

在 Firefox OS 中,大多数应用程序都是 进程外 运行的。这意味着应用程序在自己的进程中运行,而不是在主进程中运行。在将给定的 key* 事件(副本)派发到系统应用程序之后,需要时间才能将原始的 key* 事件发送到 mozbrowser-iframe-embedded-page 所在的进程。同样,在将给定的 key* 事件派发到 mozbrowser-iframe-embedded-page 的进程之后,还需要时间才能将 mozbrowserafterkey* 发送回 mozbrowser-iframe-host-page 所在的进程。

因此,mozbrowserbeforekeyup 事件可能会在 keydown 事件被派发到应用程序自己的进程之前到达 Firefox OS 主进程(系统应用程序所在的进程)。上面图 6 中演示了 key* 事件顺序的常见结果。黄色系列表示 keydown 路径,蓝色系列表示 keyup 路径。没错,这两个路径可能会交叉。

下一步

如果您正在寻找我们描述的四种场景的实现细节,以及事件处理程序示例代码,以帮助您实现智能电视遥控器的键盘事件,请密切关注 后续文章,并随时关注即将在 MDN 上发布的更完整的文档。

关于 Chun-Min Chang

更多 Chun-Min Chang 的文章……

关于 Shiqi Gao

更多 Shiqi Gao 的文章……


一条评论

  1. Miguel

    您好,

    这篇文章很有趣。感谢分享。我在我工作公司的博客上也写过类似的主题:http://blog.hubii.com/firefox-os-tv-how-to-get-events-from-remote-controller/

    我们为松下开发了首批 FirefoxOS 电视应用程序之一。:)

    2015年8月26日 下午07:48

本文评论已关闭。