toolkit/modules/SpatialNavigation.jsm

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 // -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; js2-basic-offset: 2; js2-skip-preprocessor-directives: t; -*-
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 /**
michael@0 7 * Import this module through
michael@0 8 *
michael@0 9 * Components.utils.import("resource://gre/modules/SpatialNavigation.jsm");
michael@0 10 *
michael@0 11 * Usage: (Literal class)
michael@0 12 *
michael@0 13 * SpatialNavigation.init(browser_element, optional_callback);
michael@0 14 *
michael@0 15 * optional_callback will be called when a new element is focused.
michael@0 16 *
michael@0 17 * function optional_callback(element) {}
michael@0 18 */
michael@0 19
michael@0 20 "use strict";
michael@0 21
michael@0 22 this.EXPORTED_SYMBOLS = ["SpatialNavigation"];
michael@0 23
michael@0 24 var SpatialNavigation = {
michael@0 25 init: function(browser, callback) {
michael@0 26 browser.addEventListener("keydown", function (event) {
michael@0 27 _onInputKeyPress(event, callback);
michael@0 28 }, true);
michael@0 29 }
michael@0 30 };
michael@0 31
michael@0 32 // Private stuff
michael@0 33
michael@0 34 const Cc = Components.classes;
michael@0 35 const Ci = Components.interfaces;
michael@0 36 const Cu = Components.utils;
michael@0 37
michael@0 38 Cu["import"]("resource://gre/modules/Services.jsm", this);
michael@0 39
michael@0 40 let eventListenerService = Cc["@mozilla.org/eventlistenerservice;1"]
michael@0 41 .getService(Ci.nsIEventListenerService);
michael@0 42 let focusManager = Cc["@mozilla.org/focus-manager;1"]
michael@0 43 .getService(Ci.nsIFocusManager);
michael@0 44 let windowMediator = Cc['@mozilla.org/appshell/window-mediator;1']
michael@0 45 .getService(Ci.nsIWindowMediator);
michael@0 46
michael@0 47 // Debug helpers:
michael@0 48 function dump(a) {
michael@0 49 Services.console.logStringMessage("SpatialNavigation: " + a);
michael@0 50 }
michael@0 51
michael@0 52 function dumpRect(desc, rect) {
michael@0 53 dump(desc + " " + Math.round(rect.left) + " " + Math.round(rect.top) + " " +
michael@0 54 Math.round(rect.right) + " " + Math.round(rect.bottom) + " width:" +
michael@0 55 Math.round(rect.width) + " height:" + Math.round(rect.height));
michael@0 56 }
michael@0 57
michael@0 58 function dumpNodeCoord(desc, node) {
michael@0 59 let rect = node.getBoundingClientRect();
michael@0 60 dump(desc + " " + node.tagName + " x:" + Math.round(rect.left + rect.width/2) +
michael@0 61 " y:" + Math.round(rect.top + rect.height / 2));
michael@0 62 }
michael@0 63
michael@0 64 // modifier values
michael@0 65
michael@0 66 const kAlt = "alt";
michael@0 67 const kShift = "shift";
michael@0 68 const kCtrl = "ctrl";
michael@0 69 const kNone = "none";
michael@0 70
michael@0 71 function _onInputKeyPress (event, callback) {
michael@0 72 //If Spatial Navigation isn't enabled, return.
michael@0 73 if (!PrefObserver['enabled']) {
michael@0 74 return;
michael@0 75 }
michael@0 76
michael@0 77 // Use whatever key value is available (either keyCode or charCode).
michael@0 78 // It might be useful for addons or whoever wants to set different
michael@0 79 // key to be used here (e.g. "a", "F1", "arrowUp", ...).
michael@0 80 var key = event.which || event.keyCode;
michael@0 81
michael@0 82 if (key != PrefObserver['keyCodeDown'] &&
michael@0 83 key != PrefObserver['keyCodeRight'] &&
michael@0 84 key != PrefObserver['keyCodeUp'] &&
michael@0 85 key != PrefObserver['keyCodeLeft'] &&
michael@0 86 key != PrefObserver['keyCodeReturn']) {
michael@0 87 return;
michael@0 88 }
michael@0 89
michael@0 90 if (key == PrefObserver['keyCodeReturn']) {
michael@0 91 // We report presses of the action button on a gamepad "A" as the return
michael@0 92 // key to the DOM. The behaviour of hitting the return key and clicking an
michael@0 93 // element is the same for some elements, but not all, so we handle the
michael@0 94 // ones we want (like the Select element) here:
michael@0 95 if (event.target instanceof Ci.nsIDOMHTMLSelectElement &&
michael@0 96 event.target.click) {
michael@0 97 event.target.click();
michael@0 98 event.stopPropagation();
michael@0 99 event.preventDefault();
michael@0 100 return;
michael@0 101 } else {
michael@0 102 // Leave the action key press to get reported to the DOM as a return
michael@0 103 // keypress.
michael@0 104 return;
michael@0 105 }
michael@0 106 }
michael@0 107
michael@0 108 // If it is not using the modifiers it should, return.
michael@0 109 if (!event.altKey && PrefObserver['modifierAlt'] ||
michael@0 110 !event.shiftKey && PrefObserver['modifierShift'] ||
michael@0 111 !event.crtlKey && PrefObserver['modifierCtrl']) {
michael@0 112 return;
michael@0 113 }
michael@0 114
michael@0 115 let currentlyFocused = event.target;
michael@0 116 let currentlyFocusedWindow = currentlyFocused.ownerDocument.defaultView;
michael@0 117 let bestElementToFocus = null;
michael@0 118
michael@0 119 // If currentlyFocused is an nsIDOMHTMLBodyElement then the page has just been
michael@0 120 // loaded, and this is the first keypress in the page.
michael@0 121 if (currentlyFocused instanceof Ci.nsIDOMHTMLBodyElement) {
michael@0 122 focusManager.moveFocus(currentlyFocusedWindow, null, focusManager.MOVEFOCUS_FIRST, 0);
michael@0 123 event.stopPropagation();
michael@0 124 event.preventDefault();
michael@0 125 return;
michael@0 126 }
michael@0 127
michael@0 128 if ((currentlyFocused instanceof Ci.nsIDOMHTMLInputElement &&
michael@0 129 currentlyFocused.mozIsTextField(false)) ||
michael@0 130 currentlyFocused instanceof Ci.nsIDOMHTMLTextAreaElement) {
michael@0 131 // If there is a text selection, remain in the element.
michael@0 132 if (currentlyFocused.selectionEnd - currentlyFocused.selectionStart != 0) {
michael@0 133 return;
michael@0 134 }
michael@0 135
michael@0 136 // If there is no text, there is nothing special to do.
michael@0 137 if (currentlyFocused.textLength > 0) {
michael@0 138 if (key == PrefObserver['keyCodeRight'] ||
michael@0 139 key == PrefObserver['keyCodeDown'] ) {
michael@0 140 // We are moving forward into the document.
michael@0 141 if (currentlyFocused.textLength != currentlyFocused.selectionEnd) {
michael@0 142 return;
michael@0 143 }
michael@0 144 } else if (currentlyFocused.selectionStart != 0) {
michael@0 145 return;
michael@0 146 }
michael@0 147 }
michael@0 148 }
michael@0 149
michael@0 150 let windowUtils = currentlyFocusedWindow.QueryInterface(Ci.nsIInterfaceRequestor)
michael@0 151 .getInterface(Ci.nsIDOMWindowUtils);
michael@0 152 let cssPageRect = _getRootBounds(windowUtils);
michael@0 153 let searchRect = _getSearchRect(currentlyFocused, key, cssPageRect);
michael@0 154
michael@0 155 let nodes = {};
michael@0 156 nodes.length = 0;
michael@0 157
michael@0 158 let searchRectOverflows = false;
michael@0 159
michael@0 160 while (!bestElementToFocus && !searchRectOverflows) {
michael@0 161 switch (key) {
michael@0 162 case PrefObserver['keyCodeLeft']:
michael@0 163 case PrefObserver['keyCodeRight']: {
michael@0 164 if (searchRect.top < cssPageRect.top &&
michael@0 165 searchRect.bottom > cssPageRect.bottom) {
michael@0 166 searchRectOverflows = true;
michael@0 167 }
michael@0 168 break;
michael@0 169 }
michael@0 170 case PrefObserver['keyCodeUp']:
michael@0 171 case PrefObserver['keyCodeDown']: {
michael@0 172 if (searchRect.left < cssPageRect.left &&
michael@0 173 searchRect.right > cssPageRect.right) {
michael@0 174 searchRectOverflows = true;
michael@0 175 }
michael@0 176 break;
michael@0 177 }
michael@0 178 }
michael@0 179
michael@0 180 nodes = windowUtils.nodesFromRect(searchRect.left, searchRect.top,
michael@0 181 0, searchRect.width, searchRect.height, 0,
michael@0 182 true, false);
michael@0 183 // Make the search rectangle "wider": double it's size in the direction
michael@0 184 // that is not the keypress.
michael@0 185 switch (key) {
michael@0 186 case PrefObserver['keyCodeLeft']:
michael@0 187 case PrefObserver['keyCodeRight']: {
michael@0 188 searchRect.top = searchRect.top - (searchRect.height / 2);
michael@0 189 searchRect.bottom = searchRect.top + (searchRect.height * 2);
michael@0 190 searchRect.height = searchRect.height * 2;
michael@0 191 break;
michael@0 192 }
michael@0 193 case PrefObserver['keyCodeUp']:
michael@0 194 case PrefObserver['keyCodeDown']: {
michael@0 195 searchRect.left = searchRect.left - (searchRect.width / 2);
michael@0 196 searchRect.right = searchRect.left + (searchRect.width * 2);
michael@0 197 searchRect.width = searchRect.width * 2;
michael@0 198 break;
michael@0 199 }
michael@0 200 }
michael@0 201 bestElementToFocus = _getBestToFocus(nodes, key, currentlyFocused);
michael@0 202 }
michael@0 203
michael@0 204
michael@0 205 if (bestElementToFocus === null) {
michael@0 206 // Couldn't find an element to focus.
michael@0 207 return;
michael@0 208 }
michael@0 209
michael@0 210 focusManager.setFocus(bestElementToFocus, focusManager.FLAG_SHOWRING);
michael@0 211
michael@0 212 //if it is a text element, select all.
michael@0 213 if ((bestElementToFocus instanceof Ci.nsIDOMHTMLInputElement &&
michael@0 214 bestElementToFocus.mozIsTextField(false)) ||
michael@0 215 bestElementToFocus instanceof Ci.nsIDOMHTMLTextAreaElement) {
michael@0 216 bestElementToFocus.selectionStart = 0;
michael@0 217 bestElementToFocus.selectionEnd = bestElementToFocus.textLength;
michael@0 218 }
michael@0 219
michael@0 220 if (callback != undefined) {
michael@0 221 callback(bestElementToFocus);
michael@0 222 }
michael@0 223
michael@0 224 event.preventDefault();
michael@0 225 event.stopPropagation();
michael@0 226 }
michael@0 227
michael@0 228 // Returns the bounds of the page relative to the viewport.
michael@0 229 function _getRootBounds(windowUtils) {
michael@0 230 let cssPageRect = windowUtils.getRootBounds();
michael@0 231
michael@0 232 let scrollX = {};
michael@0 233 let scrollY = {};
michael@0 234 windowUtils.getScrollXY(false, scrollX, scrollY);
michael@0 235
michael@0 236 let cssPageRectCopy = {};
michael@0 237
michael@0 238 cssPageRectCopy.right = cssPageRect.right - scrollX.value;
michael@0 239 cssPageRectCopy.left = cssPageRect.left - scrollX.value;
michael@0 240 cssPageRectCopy.top = cssPageRect.top - scrollY.value;
michael@0 241 cssPageRectCopy.bottom = cssPageRect.bottom - scrollY.value;
michael@0 242 cssPageRectCopy.width = cssPageRect.width;
michael@0 243 cssPageRectCopy.height = cssPageRect.height;
michael@0 244
michael@0 245 return cssPageRectCopy;
michael@0 246 }
michael@0 247
michael@0 248 // Returns the best node to focus from the list of nodes returned by the hit
michael@0 249 // test.
michael@0 250 function _getBestToFocus(nodes, key, currentlyFocused) {
michael@0 251 let best = null;
michael@0 252 let bestDist;
michael@0 253 let bestMid;
michael@0 254 let nodeMid;
michael@0 255 let currentlyFocusedMid = _getMidpoint(currentlyFocused);
michael@0 256 let currentlyFocusedRect = currentlyFocused.getBoundingClientRect();
michael@0 257
michael@0 258 for (let i = 0; i < nodes.length; i++) {
michael@0 259 // Reject the currentlyFocused, and all node types we can't focus
michael@0 260 if (!_canFocus(nodes[i]) || nodes[i] === currentlyFocused) {
michael@0 261 continue;
michael@0 262 }
michael@0 263
michael@0 264 // Reject all nodes that aren't "far enough" in the direction of the
michael@0 265 // keypress
michael@0 266 nodeMid = _getMidpoint(nodes[i]);
michael@0 267 switch (key) {
michael@0 268 case PrefObserver['keyCodeLeft']:
michael@0 269 if (nodeMid.x >= (currentlyFocusedMid.x - currentlyFocusedRect.width / 2)) {
michael@0 270 continue;
michael@0 271 }
michael@0 272 break;
michael@0 273 case PrefObserver['keyCodeRight']:
michael@0 274 if (nodeMid.x <= (currentlyFocusedMid.x + currentlyFocusedRect.width / 2)) {
michael@0 275 continue;
michael@0 276 }
michael@0 277 break;
michael@0 278
michael@0 279 case PrefObserver['keyCodeUp']:
michael@0 280 if (nodeMid.y >= (currentlyFocusedMid.y - currentlyFocusedRect.height / 2)) {
michael@0 281 continue;
michael@0 282 }
michael@0 283 break;
michael@0 284 case PrefObserver['keyCodeDown']:
michael@0 285 if (nodeMid.y <= (currentlyFocusedMid.y + currentlyFocusedRect.height / 2)) {
michael@0 286 continue;
michael@0 287 }
michael@0 288 break;
michael@0 289 }
michael@0 290
michael@0 291 // Initialize best to the first viable value:
michael@0 292 if (!best) {
michael@0 293 best = nodes[i];
michael@0 294 bestDist = _spatialDistance(best, currentlyFocused);
michael@0 295 continue;
michael@0 296 }
michael@0 297
michael@0 298 // Of the remaining nodes, pick the one closest to the currently focused
michael@0 299 // node.
michael@0 300 let curDist = _spatialDistance(nodes[i], currentlyFocused);
michael@0 301 if (curDist > bestDist) {
michael@0 302 continue;
michael@0 303 }
michael@0 304
michael@0 305 bestMid = _getMidpoint(best);
michael@0 306 switch (key) {
michael@0 307 case PrefObserver['keyCodeLeft']:
michael@0 308 if (nodeMid.x > bestMid.x) {
michael@0 309 best = nodes[i];
michael@0 310 bestDist = curDist;
michael@0 311 }
michael@0 312 break;
michael@0 313 case PrefObserver['keyCodeRight']:
michael@0 314 if (nodeMid.x < bestMid.x) {
michael@0 315 best = nodes[i];
michael@0 316 bestDist = curDist;
michael@0 317 }
michael@0 318 break;
michael@0 319 case PrefObserver['keyCodeUp']:
michael@0 320 if (nodeMid.y > bestMid.y) {
michael@0 321 best = nodes[i];
michael@0 322 bestDist = curDist;
michael@0 323 }
michael@0 324 break;
michael@0 325 case PrefObserver['keyCodeDown']:
michael@0 326 if (nodeMid.y < bestMid.y) {
michael@0 327 best = nodes[i];
michael@0 328 bestDist = curDist;
michael@0 329 }
michael@0 330 break;
michael@0 331 }
michael@0 332 }
michael@0 333 return best;
michael@0 334 }
michael@0 335
michael@0 336 // Returns the midpoint of a node.
michael@0 337 function _getMidpoint(node) {
michael@0 338 let mid = {};
michael@0 339 let box = node.getBoundingClientRect();
michael@0 340 mid.x = box.left + (box.width / 2);
michael@0 341 mid.y = box.top + (box.height / 2);
michael@0 342
michael@0 343 return mid;
michael@0 344 }
michael@0 345
michael@0 346 // Returns true if the node is a type that we want to focus, false otherwise.
michael@0 347 function _canFocus(node) {
michael@0 348 if (node instanceof Ci.nsIDOMHTMLLinkElement ||
michael@0 349 node instanceof Ci.nsIDOMHTMLAnchorElement) {
michael@0 350 return true;
michael@0 351 }
michael@0 352 if ((node instanceof Ci.nsIDOMHTMLButtonElement ||
michael@0 353 node instanceof Ci.nsIDOMHTMLInputElement ||
michael@0 354 node instanceof Ci.nsIDOMHTMLLinkElement ||
michael@0 355 node instanceof Ci.nsIDOMHTMLOptGroupElement ||
michael@0 356 node instanceof Ci.nsIDOMHTMLSelectElement ||
michael@0 357 node instanceof Ci.nsIDOMHTMLTextAreaElement) &&
michael@0 358 node.disabled === false) {
michael@0 359 return true;
michael@0 360 }
michael@0 361 return false;
michael@0 362 }
michael@0 363
michael@0 364 // Returns a rectangle that extends to the end of the screen in the direction that
michael@0 365 // the key is pressed.
michael@0 366 function _getSearchRect(currentlyFocused, key, cssPageRect) {
michael@0 367 let currentlyFocusedRect = currentlyFocused.getBoundingClientRect();
michael@0 368
michael@0 369 let newRect = {};
michael@0 370 newRect.left = currentlyFocusedRect.left;
michael@0 371 newRect.top = currentlyFocusedRect.top;
michael@0 372 newRect.right = currentlyFocusedRect.right;
michael@0 373 newRect.bottom = currentlyFocusedRect.bottom;
michael@0 374 newRect.width = currentlyFocusedRect.width;
michael@0 375 newRect.height = currentlyFocusedRect.height;
michael@0 376
michael@0 377 switch (key) {
michael@0 378 case PrefObserver['keyCodeLeft']:
michael@0 379 newRect.left = cssPageRect.left;
michael@0 380 newRect.width = newRect.right - newRect.left;
michael@0 381 break;
michael@0 382
michael@0 383 case PrefObserver['keyCodeRight']:
michael@0 384 newRect.right = cssPageRect.right;
michael@0 385 newRect.width = newRect.right - newRect.left;
michael@0 386 break;
michael@0 387
michael@0 388 case PrefObserver['keyCodeUp']:
michael@0 389 newRect.top = cssPageRect.top;
michael@0 390 newRect.height = newRect.bottom - newRect.top;
michael@0 391 break;
michael@0 392
michael@0 393 case PrefObserver['keyCodeDown']:
michael@0 394 newRect.bottom = cssPageRect.bottom;
michael@0 395 newRect.height = newRect.bottom - newRect.top;
michael@0 396 break;
michael@0 397 }
michael@0 398 return newRect;
michael@0 399 }
michael@0 400
michael@0 401 // Gets the distance between two points a and b.
michael@0 402 function _spatialDistance(a, b) {
michael@0 403 let mida = _getMidpoint(a);
michael@0 404 let midb = _getMidpoint(b);
michael@0 405
michael@0 406 return Math.round(Math.pow(mida.x - midb.x, 2) +
michael@0 407 Math.pow(mida.y - midb.y, 2));
michael@0 408 }
michael@0 409
michael@0 410 // Snav preference observer
michael@0 411 var PrefObserver = {
michael@0 412 register: function() {
michael@0 413 this.prefService = Cc["@mozilla.org/preferences-service;1"]
michael@0 414 .getService(Ci.nsIPrefService);
michael@0 415
michael@0 416 this._branch = this.prefService.getBranch("snav.");
michael@0 417 this._branch.QueryInterface(Ci.nsIPrefBranch2);
michael@0 418 this._branch.addObserver("", this, false);
michael@0 419
michael@0 420 // set current or default pref values
michael@0 421 this.observe(null, "nsPref:changed", "enabled");
michael@0 422 this.observe(null, "nsPref:changed", "xulContentEnabled");
michael@0 423 this.observe(null, "nsPref:changed", "keyCode.modifier");
michael@0 424 this.observe(null, "nsPref:changed", "keyCode.right");
michael@0 425 this.observe(null, "nsPref:changed", "keyCode.up");
michael@0 426 this.observe(null, "nsPref:changed", "keyCode.down");
michael@0 427 this.observe(null, "nsPref:changed", "keyCode.left");
michael@0 428 this.observe(null, "nsPref:changed", "keyCode.return");
michael@0 429 },
michael@0 430
michael@0 431 observe: function(aSubject, aTopic, aData) {
michael@0 432 if (aTopic != "nsPref:changed") {
michael@0 433 return;
michael@0 434 }
michael@0 435
michael@0 436 // aSubject is the nsIPrefBranch we're observing (after appropriate QI)
michael@0 437 // aData is the name of the pref that's been changed (relative to aSubject)
michael@0 438 switch (aData) {
michael@0 439 case "enabled":
michael@0 440 try {
michael@0 441 this.enabled = this._branch.getBoolPref("enabled");
michael@0 442 } catch(e) {
michael@0 443 this.enabled = false;
michael@0 444 }
michael@0 445 break;
michael@0 446
michael@0 447 case "xulContentEnabled":
michael@0 448 try {
michael@0 449 this.xulContentEnabled = this._branch.getBoolPref("xulContentEnabled");
michael@0 450 } catch(e) {
michael@0 451 this.xulContentEnabled = false;
michael@0 452 }
michael@0 453 break;
michael@0 454
michael@0 455 case "keyCode.modifier": {
michael@0 456 let keyCodeModifier;
michael@0 457 try {
michael@0 458 keyCodeModifier = this._branch.getCharPref("keyCode.modifier");
michael@0 459
michael@0 460 // resetting modifiers
michael@0 461 this.modifierAlt = false;
michael@0 462 this.modifierShift = false;
michael@0 463 this.modifierCtrl = false;
michael@0 464
michael@0 465 if (keyCodeModifier != this.kNone) {
michael@0 466 // we are using '+' as a separator in about:config.
michael@0 467 let mods = keyCodeModifier.split(/\++/);
michael@0 468 for (let i = 0; i < mods.length; i++) {
michael@0 469 let mod = mods[i].toLowerCase();
michael@0 470 if (mod === "")
michael@0 471 continue;
michael@0 472 else if (mod == kAlt)
michael@0 473 this.modifierAlt = true;
michael@0 474 else if (mod == kShift)
michael@0 475 this.modifierShift = true;
michael@0 476 else if (mod == kCtrl)
michael@0 477 this.modifierCtrl = true;
michael@0 478 else {
michael@0 479 keyCodeModifier = kNone;
michael@0 480 break;
michael@0 481 }
michael@0 482 }
michael@0 483 }
michael@0 484 } catch(e) { }
michael@0 485 break;
michael@0 486 }
michael@0 487
michael@0 488 case "keyCode.up":
michael@0 489 try {
michael@0 490 this.keyCodeUp = this._branch.getIntPref("keyCode.up");
michael@0 491 } catch(e) {
michael@0 492 this.keyCodeUp = Ci.nsIDOMKeyEvent.DOM_VK_UP;
michael@0 493 }
michael@0 494 break;
michael@0 495 case "keyCode.down":
michael@0 496 try {
michael@0 497 this.keyCodeDown = this._branch.getIntPref("keyCode.down");
michael@0 498 } catch(e) {
michael@0 499 this.keyCodeDown = Ci.nsIDOMKeyEvent.DOM_VK_DOWN;
michael@0 500 }
michael@0 501 break;
michael@0 502 case "keyCode.left":
michael@0 503 try {
michael@0 504 this.keyCodeLeft = this._branch.getIntPref("keyCode.left");
michael@0 505 } catch(e) {
michael@0 506 this.keyCodeLeft = Ci.nsIDOMKeyEvent.DOM_VK_LEFT;
michael@0 507 }
michael@0 508 break;
michael@0 509 case "keyCode.right":
michael@0 510 try {
michael@0 511 this.keyCodeRight = this._branch.getIntPref("keyCode.right");
michael@0 512 } catch(e) {
michael@0 513 this.keyCodeRight = Ci.nsIDOMKeyEvent.DOM_VK_RIGHT;
michael@0 514 }
michael@0 515 break;
michael@0 516 case "keyCode.return":
michael@0 517 try {
michael@0 518 this.keyCodeReturn = this._branch.getIntPref("keyCode.return");
michael@0 519 } catch(e) {
michael@0 520 this.keyCodeReturn = Ci.nsIDOMKeyEvent.DOM_VK_RETURN;
michael@0 521 }
michael@0 522 break;
michael@0 523 }
michael@0 524 }
michael@0 525 };
michael@0 526
michael@0 527 PrefObserver.register();

mercurial