Bug 753076 - Allow d-pad keys interoperate with text entry as well as virtual cursor. r=davidb

This commit is contained in:
Eitan Isaacson 2012-05-15 10:41:26 -07:00
parent 6fd4153fd7
commit 0118960ff4
2 changed files with 57 additions and 17 deletions

View File

@ -199,6 +199,21 @@ var AccessFu = {
QueryInterface(Ci.nsIAccessibleCursorable).virtualCursor;
let event = aEvent.
QueryInterface(Ci.nsIAccessibleVirtualCursorChangeEvent);
let position = pivot.position;
let doc = aEvent.DOMNode;
if (doc instanceof Ci.nsIDOMDocument && position.DOMNode) {
// Set the caret to the start of the pivot position, and move
// the focus in the same manner as browse with caret mode.
// This blurs the focus on the previous pivot position (if it
// was activated), and keeps us in a predictable spot for tab
// focus.
let sel = doc.getSelection();
sel.collapse(position.DOMNode, 0);
Cc["@mozilla.org/focus-manager;1"]
.getService(Ci.nsIFocusManager).moveFocus(
doc.defaultView, null, Ci.nsIFocusManager.MOVEFOCUS_CARET, 0);
}
let newContext = this.getNewContext(event.oldAccessible,
pivot.position);

View File

@ -18,14 +18,17 @@ var gAccRetrieval = Cc['@mozilla.org/accessibleRetrieval;1'].
getService(Ci.nsIAccessibleRetrieval);
var VirtualCursorController = {
NOT_EDITABLE: 0,
SINGLE_LINE_EDITABLE: 1,
MULTI_LINE_EDITABLE: 2,
attach: function attach(aWindow) {
this.chromeWin = aWindow;
this.chromeWin.document.addEventListener('keypress', this._onkeypress, true);
this.chromeWin.document.addEventListener('keypress', this, true);
},
detach: function detach() {
this.chromeWin.document.removeEventListener('keypress', this._onkeypress,
true);
this.chromeWin.document.removeEventListener('keypress', this, true);
},
_getBrowserApp: function _getBrowserApp() {
@ -37,26 +40,38 @@ var VirtualCursorController = {
}
},
_onkeypress: function _onkeypress(aEvent) {
let document = VirtualCursorController._getBrowserApp().
selectedBrowser.contentDocument;
dump('keypress ' + aEvent.keyCode + '\n');
handleEvent: function handleEvent(aEvent) {
let document = this._getBrowserApp().selectedBrowser.contentDocument;
let target = aEvent.target;
switch (aEvent.keyCode) {
case aEvent.DOM_VK_END:
VirtualCursorController.moveForward(document, true);
this.moveForward(document, true);
break;
case aEvent.DOM_VK_HOME:
VirtualCursorController.moveBackward(document, true);
this.moveBackward(document, true);
break;
case aEvent.DOM_VK_RIGHT:
VirtualCursorController.moveForward(document, aEvent.shiftKey);
if (this._isEditableText(target) &&
target.selectionEnd != target.textLength)
// Don't move forward if caret is not at end of entry.
// XXX: Fix for rtl
return;
this.moveForward(document, aEvent.shiftKey);
break;
case aEvent.DOM_VK_LEFT:
VirtualCursorController.moveBackward(document, aEvent.shiftKey);
if (this._isEditableText(target) &&
target.selectionEnd != 0)
// Don't move backward if caret is not at start of entry.
// XXX: Fix for rtl
return;
this.moveBackward(document, aEvent.shiftKey);
break;
case aEvent.DOM_VK_UP:
if (this._isEditableText(target) == this.MULTI_LINE_EDITABLE &&
target.selectionEnd != 0)
// Don't blur content if caret is not at start of text area.
return;
if (Services.appinfo.OS == 'Android')
// Return focus to native Android browser chrome.
Cc['@mozilla.org/android/bridge;1'].
@ -64,12 +79,10 @@ var VirtualCursorController = {
JSON.stringify({ gecko: { type: 'ToggleChrome:Focus' } }));
break;
case aEvent.DOM_VK_RETURN:
// XXX: It is true that desktop does not map the keypad enter key to
// DOM_VK_ENTER. So for desktop we require a ctrl+return instead.
if (Services.appinfo.OS == 'Android' || !aEvent.ctrlKey)
return;
case aEvent.DOM_VK_ENTER:
VirtualCursorController.activateCurrent(document);
if (this._isEditableText(target))
return;
this.activateCurrent(document);
break;
default:
return;
@ -79,6 +92,18 @@ var VirtualCursorController = {
aEvent.stopPropagation();
},
_isEditableText: function _isEditableText(aElement) {
// XXX: Support contentEditable and design mode
if (aElement instanceof Ci.nsIDOMHTMLInputElement &&
aElement.mozIsTextField(false))
return this.SINGLE_LINE_EDITABLE;
if (aElement instanceof Ci.nsIDOMHTMLTextAreaElement)
return this.MULTI_LINE_EDITABLE;
return this.NOT_EDITABLE;
},
moveForward: function moveForward(document, last) {
let virtualCursor = this.getVirtualCursor(document);
if (last) {