Send backspace to ChromeVox from Braille IME.

This makes the backspace key on the qwerty keyboard to behave like
an emulaed backspace key on a braille display when the IME is in braille
keyboard on standard keyboard mode.

BUG=310285
R=dtseng@chromium.org

Review URL: https://codereview.chromium.org/348533003

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@278615 0039d316-1c4b-4281-b951-d872f2087c98
parent cce694a7
...@@ -23,6 +23,10 @@ ...@@ -23,6 +23,10 @@
* Sent when the user typed a braille cell using the standard keyboard. * Sent when the user typed a braille cell using the standard keyboard.
* ChromeVox treats this similarly to entering braille input using the * ChromeVox treats this similarly to entering braille input using the
* braille display. * braille display.
* {type: 'backspace', requestId: string}
* Sent when the user presses the backspace key.
* ChromeVox must respond with a {@code keyEventHandled} message
* with the same request id.
* *
* Sent from ChromeVox to this IME: * Sent from ChromeVox to this IME:
* {type: 'replaceText', contextID: number, deleteBefore: number, * {type: 'replaceText', contextID: number, deleteBefore: number,
...@@ -31,6 +35,10 @@ ...@@ -31,6 +35,10 @@
* and inserts {@code newText}. {@code contextID} identifies the text field * and inserts {@code newText}. {@code contextID} identifies the text field
* to apply the update to (no change will happen if focus has moved to a * to apply the update to (no change will happen if focus has moved to a
* different field). * different field).
* {type: 'keyEventHandled', requestId: string, result: boolean}
* Response to a {@code backspace} message indicating whether the
* backspace was handled by ChromeVox or should be allowed to propagate
* through the normal event handling pipeline.
*/ */
/** /**
...@@ -132,7 +140,8 @@ BrailleIme.prototype = { ...@@ -132,7 +140,8 @@ BrailleIme.prototype = {
chrome.input.ime.onBlur.addListener(this.onBlur_.bind(this)); chrome.input.ime.onBlur.addListener(this.onBlur_.bind(this));
chrome.input.ime.onInputContextUpdate.addListener( chrome.input.ime.onInputContextUpdate.addListener(
this.onInputContextUpdate_.bind(this)); this.onInputContextUpdate_.bind(this));
chrome.input.ime.onKeyEvent.addListener(this.onKeyEvent_.bind(this)); chrome.input.ime.onKeyEvent.addListener(this.onKeyEvent_.bind(this),
['async']);
chrome.input.ime.onReset.addListener(this.onReset_.bind(this)); chrome.input.ime.onReset.addListener(this.onReset_.bind(this));
chrome.input.ime.onMenuItemActivated.addListener( chrome.input.ime.onMenuItemActivated.addListener(
this.onMenuItemActivated_.bind(this)); this.onMenuItemActivated_.bind(this));
...@@ -203,13 +212,14 @@ BrailleIme.prototype = { ...@@ -203,13 +212,14 @@ BrailleIme.prototype = {
* Called by the system when this IME is active and a key event is generated. * Called by the system when this IME is active and a key event is generated.
* @param {string} engineID Engine ID, should be 'braille'. * @param {string} engineID Engine ID, should be 'braille'.
* @param {!ChromeKeyboardEvent} event The keyboard event. * @param {!ChromeKeyboardEvent} event The keyboard event.
* @return {boolean} Whether the event was handled by this IME (true) or
* should be allowed to propagate.
* @private * @private
*/ */
onKeyEvent_: function(engineID, event) { onKeyEvent_: function(engineID, event) {
this.log_('onKeyEvent', engineID + ', ' + JSON.stringify(event)); this.log_('onKeyEvent', engineID + ', ' + JSON.stringify(event));
return this.processKey_(event); var result = this.processKey_(event);
if (result !== undefined) {
chrome.input.ime.keyEventHandled(event.requestId, result);
}
}, },
/** /**
...@@ -262,13 +272,21 @@ BrailleIme.prototype = { ...@@ -262,13 +272,21 @@ BrailleIme.prototype = {
/** /**
* Handles a qwerty key on the home row as a braille key. * Handles a qwerty key on the home row as a braille key.
* @param {!ChromeKeyboardEvent} event Keyboard event. * @param {!ChromeKeyboardEvent} event Keyboard event.
* @return {boolean} Whether the key event was handled or not. * @return {boolean|undefined} Whether the event was handled, or
* {@code undefined} if handling was delegated to ChromeVox.
* @private * @private
*/ */
processKey_: function(event) { processKey_: function(event) {
if (!this.useStandardKeyboard_) { if (!this.useStandardKeyboard_) {
return false; return false;
} }
if (event.code === 'Backspace' && event.type === 'keydown') {
this.pressed_ = 0;
this.accumulated_ = 0;
this.sendToChromeVox_(
{type: 'backspace', requestId: event.requestId});
return undefined;
}
var dot = this.CODE_TO_DOT_[event.code]; var dot = this.CODE_TO_DOT_[event.code];
if (!dot || event.altKey || event.ctrlKey || event.shiftKey || if (!dot || event.altKey || event.ctrlKey || event.shiftKey ||
event.capsLock) { event.capsLock) {
...@@ -336,6 +354,15 @@ BrailleIme.prototype = { ...@@ -336,6 +354,15 @@ BrailleIme.prototype = {
this.replaceText_(message.contextID, message.deleteBefore, this.replaceText_(message.contextID, message.deleteBefore,
message.newText); message.newText);
break; break;
case 'keyEventHandled':
message =
/** @type {{requestId: string, result: boolean}} */ (message);
chrome.input.ime.keyEventHandled(message.requestId, message.result);
break;
default:
console.error('Unknown message from ChromeVox: ' +
JSON.stringify(message));
break;
} }
}, },
......
...@@ -91,6 +91,13 @@ BrailleImeUnitTest.prototype = { ...@@ -91,6 +91,13 @@ BrailleImeUnitTest.prototype = {
chrome.input.ime = chrome.input.ime || {}; chrome.input.ime = chrome.input.ime || {};
chrome.runtime = chrome.runtime || {}; chrome.runtime = chrome.runtime || {};
localStorage = {}; localStorage = {};
this.lastSentKeyRequestId_ = 0;
this.lastHandledKeyRequestId_ = undefined;
this.lastHandledKeyResult_ = undefined;
chrome.input.ime.keyEventHandled = function(requestId, result) {
this.lastHandledKeyRequestId_ = Number(requestId);
this.lastHandledKeyResult_ = result;
}.bind(this);
this.createIme(); this.createIme();
}, },
...@@ -122,20 +129,25 @@ BrailleImeUnitTest.prototype = { ...@@ -122,20 +129,25 @@ BrailleImeUnitTest.prototype = {
this.port.messages.length = 0; this.port.messages.length = 0;
}, },
sendKeyDown: function(code, extra) { sendKeyEvent_: function(type, code, extra) {
var event = {code: code, type: 'keydown'}; var event = {type: type,
code: code,
requestId: (++this.lastSentKeyRequestId_) + ''};
for (var key in extra) { for (var key in extra) {
event[key] = extra[key]; event[key] = extra[key];
} }
return this.onKeyEvent.dispatch(ENGINE_ID, event); this.onKeyEvent.dispatch(ENGINE_ID, event);
if (this.lastSentKeyRequestId_ === this.lastHandledKeyRequestId_) {
return this.lastHandledKeyResult_;
}
},
sendKeyDown: function(code, extra) {
return this.sendKeyEvent_('keydown', code, extra);
}, },
sendKeyUp: function(code, extra) { sendKeyUp: function(code, extra) {
var event = {code: code, type: 'keyup'}; return this.sendKeyEvent_('keyup', code, extra);
for (var key in extra) {
event[key] = extra[key];
}
return this.onKeyEvent.dispatch(ENGINE_ID, event);
}, },
}; };
...@@ -201,6 +213,25 @@ TEST_F('BrailleImeUnitTest', 'KeysWhenStandardKeysEnabled', function() { ...@@ -201,6 +213,25 @@ TEST_F('BrailleImeUnitTest', 'KeysWhenStandardKeysEnabled', function() {
{type: 'brailleDots', dots: 0}])); {type: 'brailleDots', dots: 0}]));
}); });
TEST_F('BrailleImeUnitTest', 'TestBackspaceKey', function() {
this.activateIme();
// Enable standard keyboard feature.
assertFalse(this.menuItems[0].checked);
this.onMenuItemActivated.dispatch(ENGINE_ID, this.menuItems[0].id);
assertTrue(this.menuItems[0].checked);
expectEquals(undefined, this.sendKeyDown('Backspace'));
assertThat(this.port.messages,
eqJSON([{type: 'backspace',
requestId: this.lastSentKeyRequestId_ + ''}]));
this.port.onMessage.dispatch(
{type: 'keyEventHandled',
requestId: this.lastSentKeyRequestId_ + '',
result: true});
expectEquals(this.lastSentKeyRequestId_, this.lastHandledKeyRequestId_);
expectTrue(this.lastHandledKeyResult_);
});
TEST_F('BrailleImeUnitTest', 'UseStandardKeyboardSettingPreserved', function() { TEST_F('BrailleImeUnitTest', 'UseStandardKeyboardSettingPreserved', function() {
this.activateIme(); this.activateIme();
assertFalse(this.menuItems[0].checked); assertFalse(this.menuItems[0].checked);
......
...@@ -41,6 +41,12 @@ chrome.input.ime.commitText = function(parameters, opt_callback) {}; ...@@ -41,6 +41,12 @@ chrome.input.ime.commitText = function(parameters, opt_callback) {};
*/ */
chrome.input.ime.deleteSurroundingText = function(parameters, opt_callback) {}; chrome.input.ime.deleteSurroundingText = function(parameters, opt_callback) {};
/**
* @param {string} requestId
* @param {boolean} response
*/
chrome.input.ime.keyEventHandled = function(requestId, response) {};
/** /**
* @param {{engineID: string, items: Array.<chrome.input.ime.MenuItem>}} * @param {{engineID: string, items: Array.<chrome.input.ime.MenuItem>}}
* parameters * parameters
...@@ -144,6 +150,9 @@ ChromeKeyboardEvent.prototype.shiftKey; ...@@ -144,6 +150,9 @@ ChromeKeyboardEvent.prototype.shiftKey;
/** @type {boolean} */ /** @type {boolean} */
ChromeKeyboardEvent.prototype.capsLock; ChromeKeyboardEvent.prototype.capsLock;
/** @type {string} */
ChromeKeyboardEvent.prototype.requestId;
/** /**
* @constructor * @constructor
*/ */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment