Index: chrome/browser/resources/chromeos/chromevox/braille/braille_input_handler.js |
diff --git a/chrome/browser/resources/chromeos/chromevox/braille/braille_input_handler.js b/chrome/browser/resources/chromeos/chromevox/braille/braille_input_handler.js |
index 25677d5b539c9d1d536f676f39d2c15715a61c95..5dc4c9a0ed9001c2a5a71942c25795b863c8de09 100644 |
--- a/chrome/browser/resources/chromeos/chromevox/braille/braille_input_handler.js |
+++ b/chrome/browser/resources/chromeos/chromevox/braille/braille_input_handler.js |
@@ -73,9 +73,19 @@ cvox.BrailleInputHandler = function(translatorManager) { |
* @private |
*/ |
this.entryState_ = null; |
+ /** |
+ * @type {cvox.ExtraCellsSpan} |
+ * @private |
+ */ |
+ this.uncommittedCellsSpan_ = null; |
+ /** |
+ * @type {function()?} |
+ * @private |
+ */ |
+ this.uncommittedCellsChangedListener_ = null; |
this.translatorManager_.addChangeListener( |
- this.clearEntryState_.bind(this)); |
+ this.commitAndClearEntryState_.bind(this)); |
}; |
/** |
@@ -122,12 +132,18 @@ cvox.BrailleInputHandler.prototype = { |
* input state according to the new content. |
* @param {cvox.Spannable} text Text, optionally with value and selection |
* spans. |
+ * @param {function()} listener Called when the uncommitted cells |
+ * have changed. |
*/ |
- onDisplayContentChanged: function(text) { |
+ onDisplayContentChanged: function(text, listener) { |
var valueSpan = text.getSpanInstanceOf(cvox.ValueSpan); |
var selectionSpan = text.getSpanInstanceOf(cvox.ValueSelectionSpan); |
if (!(valueSpan && selectionSpan)) |
return; |
+ // Don't call the old listener any further, since new content is being |
+ // set. If the old listener is not cleared here, it could be called |
+ // spuriously if the entry state is cleared below. |
+ this.uncommittedCellsChangedListener_ = null; |
// The type casts are ok because the spans are known to exist. |
var valueStart = /** @type {number} */ (text.getSpanStart(valueSpan)); |
var valueEnd = /** @type {number} */ (text.getSpanEnd(valueSpan)); |
@@ -144,6 +160,13 @@ cvox.BrailleInputHandler.prototype = { |
this.entryState_.onTextBeforeChanged(newTextBefore); |
this.currentTextBefore_ = newTextBefore; |
this.currentTextAfter_ = text.toString().substring(selectionEnd, valueEnd); |
+ this.uncommittedCellsSpan_ = new cvox.ExtraCellsSpan(); |
+ text.setSpan(this.uncommittedCellsSpan_, selectionStart, selectionStart); |
+ if (this.entryState_ && this.entryState_.usesUncommittedCells) { |
+ this.updateUncommittedCells_( |
+ new Uint8Array(this.entryState_.cells_).buffer); |
+ } |
+ this.uncommittedCellsChangedListener_ = listener; |
}, |
/** |
@@ -164,7 +187,7 @@ cvox.BrailleInputHandler.prototype = { |
this.onBackspace_()) { |
return true; |
} else { |
- this.clearEntryState_(); |
+ this.commitAndClearEntryState_(); |
this.sendKeyEventPair_(event); |
return true; |
} |
@@ -213,14 +236,8 @@ cvox.BrailleInputHandler.prototype = { |
} |
if (!this.inputContext_) |
return false; |
- // Avoid accumulating cells forever when typing without moving the cursor |
- // by flushing the input when we see a blank cell. |
- // Note that this might switch to contracted if appropriate. |
- if (this.entryState_ && this.entryState_.lastCellIsBlank()) |
- this.clearEntryState_(); |
if (!this.entryState_) { |
- this.entryState_ = this.createEntryState_(); |
- if (!this.entryState_) |
+ if (!(this.entryState_ = this.createEntryState_())) |
return false; |
} |
this.entryState_.appendCell(dots); |
@@ -255,6 +272,7 @@ cvox.BrailleInputHandler.prototype = { |
return null; |
var uncontractedTranslator = |
this.translatorManager_.getUncontractedTranslator(); |
+ var constructor = cvox.BrailleInputHandler.EditsEntryState_; |
if (uncontractedTranslator) { |
var textBefore = this.currentTextBefore_; |
var textAfter = this.currentTextAfter_; |
@@ -264,10 +282,23 @@ cvox.BrailleInputHandler.prototype = { |
(cvox.BrailleInputHandler.STARTS_WITH_NON_WHITESPACE_RE_.test( |
textAfter))) { |
translator = uncontractedTranslator; |
+ } else { |
+ constructor = cvox.BrailleInputHandler.LateCommitEntryState_; |
} |
} |
- return new cvox.BrailleInputHandler.EditsEntryState_(this, translator); |
+ return new constructor(this, translator); |
+ }, |
+ |
+ /** |
+ * Commits the current entry state and clears it, if any. |
+ * @private |
+ */ |
+ commitAndClearEntryState_: function() { |
+ if (this.entryState_) { |
+ this.entryState_.commit(); |
+ this.clearEntryState_(); |
+ } |
}, |
/** |
@@ -276,12 +307,25 @@ cvox.BrailleInputHandler.prototype = { |
*/ |
clearEntryState_: function() { |
if (this.entryState_) { |
+ if (this.entryState_.usesUncommittedCells) |
+ this.updateUncommittedCells_(new ArrayBuffer(0)); |
this.entryState_.inputHandler_ = null; |
this.entryState_ = null; |
} |
}, |
/** |
+ * @param {ArrayBuffer} cells |
+ * @private |
+ */ |
+ updateUncommittedCells_: function(cells) { |
+ if (this.uncommittedCellsSpan_) |
+ this.uncommittedCellsSpan_.cells = cells; |
+ if (this.uncommittedCellsChangedListener_) |
+ this.uncommittedCellsChangedListener_(); |
+ }, |
+ |
+ /** |
* Called when another extension connects to this extension. Accepts |
* connections from the ChromeOS builtin Braille IME and ignores connections |
* from other extensions. |
@@ -499,9 +543,18 @@ cvox.BrailleInputHandler.EntryState_.prototype = { |
this.inputHandler_.clearEntryState_(); |
}, |
- /** @return {boolean} */ |
- lastCellIsBlank: function() { |
- return this.cells_[this.cells_.length - 1] === 0; |
+ /** |
+ * Makes sure the current text is permanently added to the edit field. |
+ * After this call, this object should be abandoned. |
+ */ |
+ commit: function() { |
+ }, |
+ |
+ /** |
+ * @return {boolean} true if the entry state uses uncommitted cells. |
+ */ |
+ get usesUncommittedCells() { |
+ return false; |
}, |
/** |
@@ -511,6 +564,9 @@ cvox.BrailleInputHandler.EntryState_.prototype = { |
*/ |
updateText_: function() { |
var cellsBuffer = new Uint8Array(this.cells_).buffer; |
+ var commit = this.lastCellIsBlank_; |
+ if (!commit && this.usesUncommittedCells) |
+ this.inputHandler_.updateUncommittedCells_(cellsBuffer); |
this.translator_.backTranslate(cellsBuffer, function(result) { |
if (result === null) { |
console.error('Error when backtranslating braille cells'); |
@@ -520,10 +576,20 @@ cvox.BrailleInputHandler.EntryState_.prototype = { |
return; |
this.sendTextChange_(result); |
this.text_ = result; |
+ if (commit) |
+ this.inputHandler_.commitAndClearEntryState_(); |
}.bind(this)); |
}, |
/** |
+ * @return {boolean} |
+ * @private |
+ */ |
+ get lastCellIsBlank_() { |
+ return this.cells_[this.cells_.length - 1] === 0; |
+ }, |
+ |
+ /** |
* Sends new text to the IME. This dhould be overriden by subclasses. |
* The old text is still available in the {@code text_} property. |
* @param {string} newText Text to send. |
@@ -585,3 +651,42 @@ cvox.BrailleInputHandler.EditsEntryState_.prototype = { |
} |
} |
}; |
+ |
+/** |
+ * Entry state that only updates the edit field when a blank cell is entered. |
+ * During the input of a single 'word', the uncommitted text is stored by the |
+ * IME. |
+ * @param {!cvox.BrailleInputHandler} inputHandler |
+ * @param {!cvox.LibLouis.Translator} translator |
+ * @constructor |
+ * @private |
+ * @extends {cvox.BrailleInputHandler.EntryState_} |
+ */ |
+cvox.BrailleInputHandler.LateCommitEntryState_ = function( |
+ inputHandler, translator) { |
+ cvox.BrailleInputHandler.EntryState_.call(this, inputHandler, translator); |
+}; |
+ |
+cvox.BrailleInputHandler.LateCommitEntryState_.prototype = { |
+ __proto__: cvox.BrailleInputHandler.EntryState_.prototype, |
+ |
+ /** @override */ |
+ commit: function() { |
+ this.inputHandler_.postImeMessage_( |
+ {type: 'commitUncommitted', |
+ contextID: this.inputHandler_.inputContext_.contextID}); |
+ }, |
+ |
+ /** @override */ |
+ get usesUncommittedCells() { |
+ return true; |
+ }, |
+ |
+ /** @override */ |
+ sendTextChange_: function(newText) { |
+ this.inputHandler_.postImeMessage_( |
+ {type: 'setUncommitted', |
+ contextID: this.inputHandler_.inputContext_.contextID, |
+ text: newText}); |
+ } |
+}; |