Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 /** | 5 /** |
| 6 * @fileoverview Puts text on a braille display. | 6 * @fileoverview Puts text on a braille display. |
| 7 * | 7 * |
| 8 */ | 8 */ |
| 9 | 9 |
| 10 goog.provide('cvox.BrailleDisplayManager'); | 10 goog.provide('cvox.BrailleDisplayManager'); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 46 this.translatedContent_ = new ArrayBuffer(0); | 46 this.translatedContent_ = new ArrayBuffer(0); |
| 47 /** | 47 /** |
| 48 * @type {!ArrayBuffer} | 48 * @type {!ArrayBuffer} |
| 49 * @private | 49 * @private |
| 50 */ | 50 */ |
| 51 this.displayedContent_ = this.translatedContent_; | 51 this.displayedContent_ = this.translatedContent_; |
| 52 /** | 52 /** |
| 53 * @type {cvox.PanStrategy} | 53 * @type {cvox.PanStrategy} |
| 54 * @private | 54 * @private |
| 55 */ | 55 */ |
| 56 this.panStrategy_ = new cvox.WrappingPanStrategy(); | 56 this.panStrategy_ = new cvox.PanStrategy(); |
| 57 /** | 57 /** |
| 58 * @type {function(!cvox.BrailleKeyEvent, !cvox.NavBraille)} | 58 * @type {function(!cvox.BrailleKeyEvent, !cvox.NavBraille)} |
| 59 * @private | 59 * @private |
| 60 */ | 60 */ |
| 61 this.commandListener_ = function() {}; | 61 this.commandListener_ = function() {}; |
| 62 /** | 62 /** |
| 63 * Current display state used for width calculations. This is different from | 63 * Current display state used for width calculations. This is different from |
| 64 * realDisplayState_ if the braille captions feature is enabled and there is | 64 * realDisplayState_ if the braille captions feature is enabled and there is |
| 65 * no hardware display connected. Otherwise, it is the same object | 65 * no hardware display connected. Otherwise, it is the same object |
| 66 * as realDisplayState_. | 66 * as realDisplayState_. |
| 67 * @type {!cvox.BrailleDisplayState} | 67 * @type {!cvox.BrailleDisplayState} |
| 68 * @private | 68 * @private |
| 69 */ | 69 */ |
| 70 this.displayState_ = {available: false, textRowCount: undefined, | 70 this.displayState_ = {available: false, textRowCount: undefined, |
| 71 textColumnCount: undefined}; | 71 textColumnCount: undefined}; |
| 72 /** | 72 /** |
| 73 * State reported from the chrome api, reflecting a real hardware | 73 * State reported from the chrome api, reflecting a real hardware |
| 74 * display. | 74 * display. |
| 75 * @type {!cvox.BrailleDisplayState} | 75 * @type {!cvox.BrailleDisplayState} |
| 76 * @private | 76 * @private |
| 77 */ | 77 */ |
| 78 this.realDisplayState_ = this.displayState_; | 78 this.realDisplayState_ = this.displayState_; |
| 79 /** | |
| 80 * @type {!Array<number>} | |
| 81 * @private | |
| 82 */ | |
| 83 this.textToBraille_ = []; | |
| 84 /** | |
| 85 * @type {!Array<number>} | |
| 86 * @private | |
| 87 */ | |
| 88 this.brailleToText_ = []; | |
| 89 | 79 |
| 90 translatorManager.addChangeListener(function() { | 80 translatorManager.addChangeListener(function() { |
| 91 this.translateContent_(this.content_, this.expansionType_); | 81 this.translateContent_(this.content_, this.expansionType_); |
| 92 }.bind(this)); | 82 }.bind(this)); |
| 93 | 83 |
| 94 chrome.storage.onChanged.addListener(function(changes, area) { | 84 chrome.storage.onChanged.addListener(function(changes, area) { |
| 95 if (area == 'local' && 'brailleWordWrap' in changes) { | 85 if (area == 'local' && 'brailleWordWrap' in changes) { |
| 96 this.updatePanStrategy_(changes.brailleWordWrap.newValue); | 86 this.updatePanStrategy_(changes.brailleWordWrap.newValue); |
| 97 } | 87 } |
| 98 }.bind(this)); | 88 }.bind(this)); |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 163 this.realDisplayState_ = newState; | 153 this.realDisplayState_ = newState; |
| 164 if (newState.available) { | 154 if (newState.available) { |
| 165 this.displayState_ = newState; | 155 this.displayState_ = newState; |
| 166 } else { | 156 } else { |
| 167 this.displayState_ = | 157 this.displayState_ = |
| 168 cvox.BrailleCaptionsBackground.getVirtualDisplayState(); | 158 cvox.BrailleCaptionsBackground.getVirtualDisplayState(); |
| 169 } | 159 } |
| 170 var newSize = this.displayState_.textColumnCount * | 160 var newSize = this.displayState_.textColumnCount * |
| 171 this.displayState_.textRowCount || 0; | 161 this.displayState_.textRowCount || 0; |
| 172 if (oldSize != newSize) { | 162 if (oldSize != newSize) { |
| 173 this.panStrategy_.setDisplaySize(newSize); | 163 // TODO might need to change when display is plugged in. |
|
David Tseng
2016/11/14 21:05:08
This is going to break for real devices. Look at t
ultimatedbz
2016/11/15 18:04:02
Right, I'm thinking that if a newState is availabl
| |
| 164 this.panStrategy_.setDisplaySize(parseInt( | |
| 165 localStorage['virtualBrailleRows'], 10), | |
| 166 parseInt(localStorage['virtualBrailleColumns'], 10)); | |
| 174 } | 167 } |
| 175 this.refresh_(); | 168 this.refresh_(); |
| 176 }; | 169 }; |
| 177 | 170 |
| 178 | 171 |
| 179 /** | 172 /** |
| 180 * Called when the state of braille captions changes. | 173 * Called when the state of braille captions changes. |
| 181 * @private | 174 * @private |
| 182 */ | 175 */ |
| 183 cvox.BrailleDisplayManager.prototype.onCaptionsStateChanged_ = function() { | 176 cvox.BrailleDisplayManager.prototype.onCaptionsStateChanged_ = function() { |
| 184 // Force reevaluation of the display state based on our stored real | 177 // Force reevaluation of the display state based on our stored real |
| 185 // hardware display state, meaning that if a real display is connected, | 178 // hardware display state, meaning that if a real display is connected, |
| 186 // that takes precedence over the state from the captions 'virtual' display. | 179 // that takes precedence over the state from the captions 'virtual' display. |
| 187 this.refreshDisplayState_(this.realDisplayState_); | 180 this.refreshDisplayState_(this.realDisplayState_); |
| 188 }; | 181 }; |
| 189 | 182 |
| 190 | 183 |
| 191 /** @private */ | 184 /** |
| 185 * Refreshes what is shown on the physical braille display and the virtual | |
| 186 * braille captions display. | |
| 187 * @private */ | |
| 192 cvox.BrailleDisplayManager.prototype.refresh_ = function() { | 188 cvox.BrailleDisplayManager.prototype.refresh_ = function() { |
| 193 if (!this.displayState_.available) { | 189 if (!this.displayState_.available) { |
| 194 return; | 190 return; |
| 195 } | 191 } |
| 196 var viewPort = this.panStrategy_.viewPort; | 192 var brailleBuf = this.panStrategy_.getCurrentBrailleSlice(); |
| 197 var buf = this.displayedContent_.slice(viewPort.start, viewPort.end); | 193 var textBuf = this.panStrategy_.getCurrentTextSlice(); |
| 198 if (this.realDisplayState_.available) { | 194 if (this.realDisplayState_.available) { |
| 199 chrome.brailleDisplayPrivate.writeDots(buf, buf.byteLength, 1); | 195 chrome.brailleDisplayPrivate.writeDots(brailleBuf, |
| 196 brailleBuf.byteLength, 1); | |
| 200 } | 197 } |
| 201 if (cvox.BrailleCaptionsBackground.isEnabled()) { | 198 if (cvox.BrailleCaptionsBackground.isEnabled()) { |
| 202 var start = this.brailleToTextPosition_(viewPort.start); | 199 cvox.BrailleCaptionsBackground.setContent(textBuf, brailleBuf, |
| 203 var end = this.brailleToTextPosition_(viewPort.end); | 200 this.panStrategy_.brailleToText, this.panStrategy_.offsetsForSlices); |
| 204 cvox.BrailleCaptionsBackground.setContent( | |
| 205 this.content_.text.toString().substring(start, end), buf, | |
| 206 this.brailleToText_); | |
| 207 } | 201 } |
| 208 }; | 202 }; |
| 209 | 203 |
| 210 | |
| 211 /** | 204 /** |
| 212 * @param {!cvox.NavBraille} newContent New display content. | 205 * @param {!cvox.NavBraille} newContent New display content. |
| 213 * @param {cvox.ExpandingBrailleTranslator.ExpansionType} newExpansionType | 206 * @param {cvox.ExpandingBrailleTranslator.ExpansionType} newExpansionType |
| 214 * How the value part of of the new content should be expanded | 207 * How the value part of of the new content should be expanded |
| 215 * with regards to contractions. | 208 * with regards to contractions. |
| 216 * @private | 209 * @private |
| 217 */ | 210 */ |
| 218 cvox.BrailleDisplayManager.prototype.translateContent_ = function( | 211 cvox.BrailleDisplayManager.prototype.translateContent_ = function( |
| 219 newContent, newExpansionType) { | 212 newContent, newExpansionType) { |
| 220 var writeTranslatedContent = function(cells, textToBraille, brailleToText) { | 213 var writeTranslatedContent = function(cells, textToBraille, brailleToText) { |
| 221 this.content_ = newContent; | 214 this.content_ = newContent; |
| 222 this.expansionType_ = newExpansionType; | 215 this.expansionType_ = newExpansionType; |
| 223 this.textToBraille_ = textToBraille; | |
| 224 this.brailleToText_ = brailleToText; | |
| 225 var startIndex = this.content_.startIndex; | 216 var startIndex = this.content_.startIndex; |
| 226 var endIndex = this.content_.endIndex; | 217 var endIndex = this.content_.endIndex; |
| 227 var targetPosition; | 218 var targetPosition; |
| 228 if (startIndex >= 0) { | 219 if (startIndex >= 0) { |
| 229 var translatedStartIndex; | 220 var translatedStartIndex; |
| 230 var translatedEndIndex; | 221 var translatedEndIndex; |
| 231 if (startIndex >= textToBraille.length) { | 222 if (startIndex >= textToBraille.length) { |
| 232 // Allow the cells to be extended with one extra cell for | 223 // Allow the cells to be extended with one extra cell for |
| 233 // a carret after the last character. | 224 // a carret after the last character. |
| 234 var extCells = new ArrayBuffer(cells.byteLength + 1); | 225 var extCells = new ArrayBuffer(cells.byteLength + 1); |
| 235 new Uint8Array(extCells).set(new Uint8Array(cells)); | 226 new Uint8Array(extCells).set(cells); |
| 236 // Last byte is initialized to 0. | 227 // Last byte is initialized to 0. |
| 237 cells = extCells; | 228 cells = extCells; |
| 238 translatedStartIndex = cells.byteLength - 1; | 229 translatedStartIndex = cells.byteLength - 1; |
| 239 } else { | 230 } else { |
| 240 translatedStartIndex = textToBraille[startIndex]; | 231 translatedStartIndex = textToBraille[startIndex]; |
| 241 } | 232 } |
| 242 if (endIndex >= textToBraille.length) { | 233 if (endIndex >= textToBraille.length) { |
| 243 // endIndex can't be past-the-end of the last cell unless | 234 // endIndex can't be past-the-end of the last cell unless |
| 244 // startIndex is too, so we don't have to do another | 235 // startIndex is too, so we don't have to do another |
| 245 // extension here. | 236 // extension here. |
| 246 translatedEndIndex = cells.byteLength; | 237 translatedEndIndex = cells.byteLength; |
| 247 } else { | 238 } else { |
| 248 translatedEndIndex = textToBraille[endIndex]; | 239 translatedEndIndex = textToBraille[endIndex]; |
| 249 } | 240 } |
| 250 this.translatedContent_ = cells; | 241 this.translatedContent_ = cells; |
| 251 // Copy the translated content to a separate buffer and add the cursor | 242 // Copy the translated content to a separate buffer and add the cursor |
| 252 // to it. | 243 // to it. |
| 253 this.displayedContent_ = new ArrayBuffer(cells.byteLength); | 244 this.displayedContent_ = new ArrayBuffer(cells.byteLength); |
| 254 new Uint8Array(this.displayedContent_).set(new Uint8Array(cells)); | 245 new Uint8Array(this.displayedContent_).set(cells); |
| 255 this.writeCursor_(this.displayedContent_, | 246 this.writeCursor_(this.displayedContent_, |
| 256 translatedStartIndex, translatedEndIndex); | 247 translatedStartIndex, translatedEndIndex); |
| 257 targetPosition = translatedStartIndex; | 248 targetPosition = translatedStartIndex; |
| 258 } else { | 249 } else { |
| 259 this.translatedContent_ = this.displayedContent_ = cells; | 250 this.translatedContent_ = this.displayedContent_ = cells; |
| 260 targetPosition = 0; | 251 targetPosition = 0; |
| 261 } | 252 } |
| 262 this.panStrategy_.setContent(this.translatedContent_, targetPosition); | 253 this.panStrategy_.setContent(this.content_.text.toString(), |
| 254 this.translatedContent_, brailleToText); | |
| 255 | |
| 263 this.refresh_(); | 256 this.refresh_(); |
| 264 }.bind(this); | 257 }.bind(this); |
| 265 | 258 |
| 266 var translator = this.translatorManager_.getExpandingTranslator(); | 259 var translator = this.translatorManager_.getExpandingTranslator(); |
| 267 if (!translator) { | 260 if (!translator) { |
| 268 writeTranslatedContent(new ArrayBuffer(0), [], []); | 261 writeTranslatedContent(new ArrayBuffer(0), [], []); |
| 269 } else { | 262 } else { |
| 270 translator.translate( | 263 translator.translate( |
| 271 newContent.text, | 264 newContent.text, |
| 272 newExpansionType, | 265 newExpansionType, |
| 273 writeTranslatedContent); | 266 writeTranslatedContent); |
| 274 } | 267 } |
| 275 }; | 268 }; |
| 276 | 269 |
| 277 | 270 |
| 278 /** | 271 /** |
| 279 * @param {cvox.BrailleKeyEvent} event The key event. | 272 * @param {cvox.BrailleKeyEvent} event The key event. |
| 280 * @private | 273 * @private |
| 281 */ | 274 */ |
| 282 cvox.BrailleDisplayManager.prototype.onKeyEvent_ = function(event) { | 275 cvox.BrailleDisplayManager.prototype.onKeyEvent_ = function(event) { |
| 283 switch (event.command) { | 276 switch (event.command) { |
| 284 case cvox.BrailleKeyCommand.PAN_LEFT: | 277 case cvox.BrailleKeyCommand.PAN_LEFT: |
| 285 this.panLeft_(); | 278 this.panLeft_(); |
| 286 break; | 279 break; |
| 287 case cvox.BrailleKeyCommand.PAN_RIGHT: | 280 case cvox.BrailleKeyCommand.PAN_RIGHT: |
| 288 this.panRight_(); | 281 this.panRight_(); |
| 289 break; | 282 break; |
| 290 case cvox.BrailleKeyCommand.ROUTING: | 283 case cvox.BrailleKeyCommand.ROUTING: |
| 284 /* TODO | |
| 291 event.displayPosition = this.brailleToTextPosition_( | 285 event.displayPosition = this.brailleToTextPosition_( |
| 292 event.displayPosition + this.panStrategy_.viewPort.start); | 286 event.displayPosition + this.panStrategy_.viewPort.start); |
| 293 // fall through | 287 // fall through |
| 288 // */ | |
|
David Tseng
2016/11/14 21:05:08
Please don't comment out code like this with a TOD
ultimatedbz
2016/11/15 00:01:17
Hey David! Noted, my intentions weren't for this t
| |
| 294 default: | 289 default: |
| 295 this.commandListener_(event, this.content_); | 290 this.commandListener_(event, this.content_); |
| 296 break; | 291 break; |
| 297 } | 292 } |
| 298 }; | 293 }; |
| 299 | 294 |
| 300 | 295 |
| 301 /** | 296 /** |
| 302 * Shift the display by one full display size and refresh the content. | 297 * Shift the display by one full display size and refresh the content. |
| 303 * Sends the appropriate command if the display is already at the leftmost | 298 * Sends the appropriate command if the display is already at the leftmost |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 361 /** | 356 /** |
| 362 * Returns the text position corresponding to an absolute braille position, | 357 * Returns the text position corresponding to an absolute braille position, |
| 363 * that is not accounting for the current pan position. | 358 * that is not accounting for the current pan position. |
| 364 * @private | 359 * @private |
| 365 * @param {number} braillePosition Braille position relative to the startof | 360 * @param {number} braillePosition Braille position relative to the startof |
| 366 * the translated content. | 361 * the translated content. |
| 367 * @return {number} The mapped position in code units. | 362 * @return {number} The mapped position in code units. |
| 368 */ | 363 */ |
| 369 cvox.BrailleDisplayManager.prototype.brailleToTextPosition_ = | 364 cvox.BrailleDisplayManager.prototype.brailleToTextPosition_ = |
| 370 function(braillePosition) { | 365 function(braillePosition) { |
| 371 var mapping = this.brailleToText_; | 366 // TODO I'll need to support this function |
| 367 var mapping = this.panStrategy_.brailleToText; | |
| 372 if (braillePosition < 0) { | 368 if (braillePosition < 0) { |
| 373 // This shouldn't happen. | 369 // This shouldn't happen. |
| 374 console.error('WARNING: Braille position < 0: ' + braillePosition); | 370 console.error('WARNING: Braille position < 0: ' + braillePosition); |
| 375 return 0; | 371 return 0; |
| 376 } else if (braillePosition >= mapping.length) { | 372 } else if (braillePosition >= mapping.length) { |
| 377 // This happens when the user clicks on the right part of the display | 373 // This happens when the user clicks on the right part of the display |
| 378 // when it is not entirely filled with content. Allow addressing the | 374 // when it is not entirely filled with content. Allow addressing the |
| 379 // position after the last character. | 375 // position after the last character. |
| 380 return this.content_.text.length; | 376 return this.content_.text.length; |
| 381 } else { | 377 } else { |
| 382 return mapping[braillePosition]; | 378 return mapping[braillePosition]; |
| 383 } | 379 } |
| 384 }; | 380 }; |
| 385 | 381 |
| 386 | 382 |
| 387 /** | 383 /** |
| 388 * @param {boolean} wordWrap | 384 * @param {boolean} wordWrap |
| 389 * @private | 385 * @private |
| 390 */ | 386 */ |
| 391 cvox.BrailleDisplayManager.prototype.updatePanStrategy_ = function(wordWrap) { | 387 cvox.BrailleDisplayManager.prototype.updatePanStrategy_ = function(wordWrap) { |
| 392 var newStrategy = wordWrap ? new cvox.WrappingPanStrategy() : | 388 this.panStrategy_.setPanStrategy(wordWrap); |
| 393 new cvox.FixedPanStrategy(); | |
| 394 newStrategy.setDisplaySize(this.displayState_.textColumnCount || 0); | |
| 395 newStrategy.setContent(this.translatedContent_, | |
| 396 this.panStrategy_.viewPort.start); | |
| 397 this.panStrategy_ = newStrategy; | |
| 398 this.refresh_(); | 389 this.refresh_(); |
| 399 }; | 390 }; |
| OLD | NEW |