本文将探讨如何为系统核心组件(例如输入键盘)添加功能。事实证明,这非常简单!
在开始之前,请观看 Daniel Hooper 的这段概念视频,了解我们想要实现的目标。
很酷,对吧?对其他移动平台进行此类更改将非常困难,甚至是不可能的,但在 Firefox OS 中,这非常简单,只需不到 50 行代码。
计划
从概念上讲,我们想要实现的目标是:当用户在键盘区域上滑动手指时,输入字段中的光标会移动一段距离,并且移动方向与滑动方向(左或右)成正比。
由于常见的情况是用户可能按错了键,并希望滑动到附近的键进行更正,因此我们只有在滑动距离超过单个键的宽度时才会开始移动光标。
准备你的环境
为了开始破解 Firefox OS 本身,你需要一个 Gaia 的副本(构成 Firefox OS 前端的一组 Web 应用)和 B2G 桌面版(在设备上使用的 B2G 应用运行时构建版本,所有应用都应像在设备上一样运行)。
你可以查看 Mozilla Hacks 的这篇上一篇文章,其中我们指导你完成 Gaia 的设置和破解。在https://wiki.mozilla.org/Gaia/Hacking 还可以找到设置此环境的完整指南。
一旦你在 B2G 中运行 Gaia,你就可以开始破解了!
准备破解!
Firefox OS 完全使用 HTML5,在内部由多个“应用”组成。我们可以在之前克隆的 gaia 存储库中的 apps
文件夹中找到主要系统应用,包括我们将要修改的键盘应用。
在这篇文章中,我们只修改 apps/keyboard/js/keyboard.js
,这里
包含了大量键盘逻辑。
我们首先在文件顶部初始化一些额外的变量,这些变量将帮助我们稍后跟踪滑动。
var swipeStartMovePos = null; // Starting point of the swiping
var swipeHappening = false; // Are we in the middle of swiping?
var swipeLastMousex = -1; // Previous mouse position
var swipeMouseTravel = 0; // Amount traveled by the finger so far
var swipeStepWidth = 0; // Width of a single keyboard key
接下来,我们应该找到键盘处理触摸事件的位置。在keyboard.js
的顶部,我们看到声明了触摸事件的事件处理程序。
声明
var eventHandlers = {
'touchstart': onTouchStart,
'mousedown': onMouseDown,
'mouseup': onMouseUp,
'mousemove': onMouseMove
};
很好!现在我们需要存储初始触摸事件的坐标。onTouchStart
和 onMouseDown
在完成各自的触摸后任务后都会最终调用函数 startPress
,因此我们将在这里处理存储坐标。
startPress
对按下键时的一些操作进行了处理,例如突出显示键或检查用户是否按下退格键。我们将在之后编写我们的逻辑。一个方便的事情是,其签名中的一个参数是 coords
,它指的是用户开始触摸的坐标(在键盘元素的上下文中)。因此,存储坐标就像这样
function startPress(target, coords, touchId) {
swipeStartMovePos = { x: coords.pageX, y: coords.pageY };
...
这样,我们就可以随时获取上次触摸事件开始点的坐标。
但是,我们实现的核心部分将在 mousemove
事件期间发生。我们看到函数 onMouseMove
只是一个简单的代理函数,用于更大的 movePress
函数(在该函数中处理“鼠标”移动)。在这里我们将编写我们的光标滑动逻辑。
我们将使用键盘键的宽度作为我们的通用度量。由于键盘键的宽度在不同设备上有所不同,因此我们首先必须通过调用 IMERender
中的方法来获取它,IMERender
是控制键盘如何在屏幕上呈现的对象。
swipeStepWidth = swipeStepWidth || IMERender.getKeyWidth();
现在我们可以检查是否正在发生滑动,以及滑动是否超过 swipeStepWidth
。很方便的是,我们的 movePress
函数也会传递 coords
对象。
if (swipeHappening || (swipeStartMovePos && Math.abs(swipeStartMovePos.x - coords.pageX) > swipeStepWidth)) {
我们的大部分逻辑都将在该“if”块内。现在我们知道正在发生滑动,我们必须确定滑动的方向,为向右分配 1
,为向左分配 -1
到我们之前初始化的变量 swipeDirection
。之后,我们将移动的距离添加到变量 swipeMouseTravel
中,并将 swipeLastMousex
设置为当前触摸坐标。
var swipeDirection = coords.pageX > swipeLastMousex ? 1 : -1;
if (swipeLastMousex > -1) {
swipeMouseTravel += Math.abs(coords.pageX - swipeLastMousex);
}
swipeLastMousex = coords.pageX;
好的,现在我们必须确定用户手指移动的像素将如何转换为光标移动。让我们将其设为键盘键宽度的一半。这意味着,对于移动的每 swipeStepWidth / 2
像素,输入字段中的光标将移动一个字符。
我们移动光标的方式有点笨拙。我们所做的是模拟用户按下“左箭头”或“右箭头”,即使这些键在手机的虚拟键盘中根本不存在。这使我们能够移动输入字段中的光标。不是理想的方法,但 Mozilla 即将推出新的键盘 IME API,该 API 将为程序员提供一个适当的 API 来操作光标位置和选择。目前,我们只需使用变通方法。
var stepDistance = swipeStepWidth / 2;
if (swipeMouseTravel > stepDistance) {
var times = Math.floor(swipeMouseTravel / stepDistance);
swipeMouseTravel = 0;
for (var i = 0; i < times; i++)
navigator.mozKeyboard.sendKey(swipeDirection === -1 ? 37 : 39, undefined);
}
之后,我们只需要确认是否正在发生滑动,并对在文件其他区域初始化的时间超时和间隔进行一些清理,因为我们的新滑动功能,否则这些超时和间隔将不会执行。我们还调用 hideAlternatives
以避免键盘在滑动时向我们显示备选字符。
swipeHappening = true;
clearTimeout(deleteTimeout);
clearInterval(deleteInterval);
clearTimeout(menuTimeout);
hideAlternatives();
return;
唯一剩下的就是当用户抬起手指离开屏幕时重置我们设置的所有值。此事件的处理程序是 onMouseUp
,它会调用函数 endPress
,我们将在其开头放置我们的逻辑。
// The user is releasing a key so the key has been pressed. The meat is here.
function endPress(target, coords, touchId) {
swipeStartMovePos = null;
...
if (swipeHappening === true) {
swipeHappening = false;
swipeLastMousex = -1;
return;
}
有了这最后一点,我们的实现就完成了。这是我制作的工作实现的粗略视频。
你可以在 GitHub 上查看完整的实现代码更改。
结论
为 Firefox OS 贡献错误修复或功能就像获取 Gaia、B2G 并开始使用 HTML5 进行破解一样简单。如果你精通 JavaScript 编程并且熟悉制作网页,那么你就可以为 Mozilla 的移动操作系统做出贡献。
附录:寻找工作区域
如果你已经知道要解决的错误或要在 Firefox OS 中实现的功能,首先检查它是否已在 Bugzilla 中提交,Bugzilla 是 Mozilla 用于跟踪错误的问题存储库。如果没有,请随时添加。否则,如果你正在寻找新的错误来修复,一个快速搜索将显示许多尚未分配的新错误。请随意选择它们!
关于 Sergi Mansilla
Sergi 是 Telenor Comoyo Firefox OS 团队的首席开发人员。过去,他曾是 Cloud9 IDE 的开发人员,并负责为 TomTom 设备的 UI 提供支持的 JavaScript 框架。他对编程语言痴迷,并且总是在业余时间处理多个项目,这些项目通常涉及 JavaScript,无论是在前端、后端还是两者兼而有之。当他不进行破解时,你会发现他正在旅行、在某个会议上发表演讲或在某个热带纬度潜水。Sergi 目前居住在阿姆斯特丹。
关于 Robert Nyman [荣誉编辑]
技术布道师和 Mozilla Hacks 编辑。发表关于 HTML5、JavaScript 和开放网络的演讲和博客。Robert 坚定地相信 HTML5 和开放网络,自 1999 年以来一直从事 Web 前端开发工作——在瑞典和纽约市。他还经常在http://robertnyman.com 发布博客,并且喜欢旅行和结识新朋友。
14 条评论