Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(116)

Side by Side Diff: chrome/browser/resources/chromeos/chromevox/cvox2/background/output.js

Issue 845693004: Initial implementation of continuous read for ChromeVox Next. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Remove e2e test. Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 Provides output services for ChromeVox. 6 * @fileoverview Provides output services for ChromeVox.
7 */ 7 */
8 8
9 goog.provide('Output'); 9 goog.provide('Output');
10 goog.provide('Output.EventType'); 10 goog.provide('Output.EventType');
(...skipping 22 matching lines...) Expand all
33 * an AutomationNode. Specialized values include role and state. Attributes 33 * an AutomationNode. Specialized values include role and state. Attributes
34 * available for substitution are AutomationNode.prototype.attributes and 34 * available for substitution are AutomationNode.prototype.attributes and
35 * AutomationNode.prototype.state. 35 * AutomationNode.prototype.state.
36 * For example, $value $role $enabled 36 * For example, $value $role $enabled
37 * @ prefix: used to substitute a message. Note the ability to specify params to 37 * @ prefix: used to substitute a message. Note the ability to specify params to
38 * the message. For example, '@tag_html' '@selected_index($text_sel_start, 38 * the message. For example, '@tag_html' '@selected_index($text_sel_start,
39 * $text_sel_end'). 39 * $text_sel_end').
40 * = suffix: used to specify substitution only if not previously appended. 40 * = suffix: used to specify substitution only if not previously appended.
41 * For example, $name= would insert the name attribute only if no name 41 * For example, $name= would insert the name attribute only if no name
42 * attribute had been inserted previously. 42 * attribute had been inserted previously.
43 * @param {!cursors.Range} range
44 * @param {cursors.Range} prevRange
45 * @param {chrome.automation.EventType|Output.EventType} type
46 * @param {{braille: (boolean|undefined), speech: (boolean|undefined)}=}
47 * opt_options
48 * @constructor 43 * @constructor
49 */ 44 */
50 Output = function(range, prevRange, type, opt_options) { 45 Output = function() {
51 opt_options = opt_options || {braille: true, speech: true};
52 // TODO(dtseng): Include braille specific rules. 46 // TODO(dtseng): Include braille specific rules.
53 /** @type {!cvox.Spannable} */ 47 /** @type {!cvox.Spannable} */
54 this.buffer_ = new cvox.Spannable(); 48 this.buffer_ = new cvox.Spannable();
55 /** @type {!cvox.Spannable} */ 49 /** @type {!cvox.Spannable} */
56 this.brailleBuffer_ = new cvox.Spannable(); 50 this.brailleBuffer_ = new cvox.Spannable();
57 /** @type {!Array.<Object>} */ 51 /** @type {!Array.<Object>} */
58 this.locations_ = []; 52 this.locations_ = [];
53 /** @type {function()} */
54 this.speechStartCallback_ = function() {};
55 /** @type {function()} */
56 this.speechEndCallback_ = function() {};
57 /** @type {function()} */
58 this.speechInterruptedCallback_ = function() {};
59 59
60 /** 60 /**
61 * Current global options. 61 * Current global options.
62 * @type {{speech: boolean, braille: boolean, location: boolean}} 62 * @type {{speech: boolean, braille: boolean, location: boolean}}
63 */ 63 */
64 this.formatOptions_ = {speech: true, braille: false, location: true}; 64 this.formatOptions_ = {speech: true, braille: false, location: true};
65
66 this.render_(range, prevRange, type);
67 if (opt_options.speech)
68 this.handleSpeech();
69 if (opt_options.braille)
70 this.handleBraille();
71 this.handleDisplay();
72 }; 65 };
73 66
74 /** 67 /**
75 * Delimiter to use between output values. 68 * Delimiter to use between output values.
76 * @type {string} 69 * @type {string}
77 */ 70 */
78 Output.SPACE = ' '; 71 Output.SPACE = ' ';
79 72
80 /** 73 /**
81 * Rules specifying format of AutomationNodes for output. 74 * Rules specifying format of AutomationNodes for output.
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
233 Output.prototype = { 226 Output.prototype = {
234 /** 227 /**
235 * Gets the output buffer for speech. 228 * Gets the output buffer for speech.
236 * @return {!cvox.Spannable} 229 * @return {!cvox.Spannable}
237 */ 230 */
238 getBuffer: function() { 231 getBuffer: function() {
239 return this.buffer_; 232 return this.buffer_;
240 }, 233 },
241 234
242 /** 235 /**
243 * Handle output to speech. 236 * Specify ranges for speech.
237 * @param {!cursors.Range} range
238 * @param {cursors.Range} prevRange
239 * @param {chrome.automation.EventType|Output.EventType} type
240 * @return {!Output}
244 */ 241 */
245 handleSpeech: function() { 242 withSpeech: function(range, prevRange, type) {
243 this.formatOptions_ = {speech: true, braille: false, location: true};
244 this.render_(range, prevRange, type, this.buffer_);
245 return this;
246 },
247
248 /**
249 * Specify ranges for braille.
250 * @param {!cursors.Range} range
251 * @param {cursors.Range} prevRange
252 * @param {chrome.automation.EventType|Output.EventType} type
253 * @return {!Output}
254 */
255 withBraille: function(range, prevRange, type) {
256 this.formatOptions_ = {speech: false, braille: true, location: false};
257 this.render_(range, prevRange, type, this.brailleBuffer_);
258 return this;
259 },
260
261 /**
262 * Specify the same ranges for speech and braille.
263 * @param {!cursors.Range} range
264 * @param {cursors.Range} prevRange
265 * @param {chrome.automation.EventType|Output.EventType} type
266 * @return {!Output}
267 */
268 withSpeechAndBraille: function(range, prevRange, type) {
269 this.withSpeech(range, prevRange, type);
270 this.withBraille(range, prevRange, type);
271 return this;
272 },
273
274 /**
275 * Triggers callback for a speech event.
276 * @param {function()} callback
277 */
278 onSpeechStart: function(callback) {
279 this.speechStartCallback_ = callback;
280 return this;
281 },
282
283 /**
284 * Triggers callback for a speech event.
285 * @param {function()} callback
286 */
287 onSpeechEnd: function(callback) {
288 this.speechEndCallback_ = callback;
289 return this;
290 },
291
292 /**
293 * Triggers callback for a speech event.
294 * @param {function()} callback
295 */
296 onSpeechInterrupted: function(callback) {
297 this.speechInterruptedCallback_ = callback;
298 return this;
299 },
300
301 /**
302 * Executes all specified output.
303 */
304 go: function() {
305 // Speech.
246 var buff = this.buffer_; 306 var buff = this.buffer_;
247 if (!buff.toString())
248 return;
249 307
250 cvox.ChromeVox.tts.speak(buff.toString(), cvox.QueueMode.FLUSH); 308 var onEvent = function(evt) {
309 switch (evt.type) {
310 case 'start': this.speechStartCallback_(); break;
311 case 'end': this.speechEndCallback_(); break;
312 case 'interrupted': this.speechInterruptedCallback_(); break;
313 }
314 }.bind(this);
315
316 if (buff.toString()) {
317 cvox.ChromeVox.tts.speak(
318 buff.toString(), cvox.QueueMode.FLUSH, {onEvent: onEvent});
319 }
320
251 var actions = buff.getSpansInstanceOf(Output.Action); 321 var actions = buff.getSpansInstanceOf(Output.Action);
252 if (actions) { 322 if (actions) {
253 actions.forEach(function(a) { 323 actions.forEach(function(a) {
254 a.run(); 324 a.run();
255 }); 325 });
256 } 326 }
257 },
258 327
259 /** 328 // Braille.
260 * Handles output to braille.
261 */
262 handleBraille: function() {
263 var selSpan = 329 var selSpan =
264 this.brailleBuffer_.getSpanInstanceOf(Output.SelectionSpan); 330 this.brailleBuffer_.getSpanInstanceOf(Output.SelectionSpan);
265 var startIndex = -1, endIndex = -1; 331 var startIndex = -1, endIndex = -1;
266 if (selSpan) { 332 if (selSpan) {
267 var valueStart = this.brailleBuffer_.getSpanStart(selSpan); 333 var valueStart = this.brailleBuffer_.getSpanStart(selSpan);
268 var valueEnd = this.brailleBuffer_.getSpanEnd(selSpan); 334 var valueEnd = this.brailleBuffer_.getSpanEnd(selSpan);
269 if (valueStart === undefined || valueEnd === undefined) { 335 if (valueStart === undefined || valueEnd === undefined) {
270 valueStart = -1; 336 valueStart = -1;
271 valueEnd = -1; 337 valueEnd = -1;
272 } else { 338 } else {
273 startIndex = valueStart + selSpan.startIndex; 339 startIndex = valueStart + selSpan.startIndex;
274 endIndex = valueStart + selSpan.endIndex; 340 endIndex = valueStart + selSpan.endIndex;
275 this.brailleBuffer_.setSpan(new cvox.BrailleUtil.ValueSpan(valueStart), 341 this.brailleBuffer_.setSpan(new cvox.BrailleUtil.ValueSpan(valueStart),
276 valueStart, valueEnd); 342 valueStart, valueEnd);
277 this.brailleBuffer_.setSpan(new cvox.BrailleUtil.ValueSelectionSpan(), 343 this.brailleBuffer_.setSpan(new cvox.BrailleUtil.ValueSelectionSpan(),
278 startIndex, endIndex); 344 startIndex, endIndex);
279 } 345 }
280 } 346 }
281 347
282 var output = new cvox.NavBraille({ 348 var output = new cvox.NavBraille({
283 text: this.brailleBuffer_, 349 text: this.brailleBuffer_,
284 startIndex: startIndex, 350 startIndex: startIndex,
285 endIndex: endIndex 351 endIndex: endIndex
286 }); 352 });
287 353
288 cvox.ChromeVox.braille.write(output); 354 if (this.brailleBuffer_)
289 }, 355 cvox.ChromeVox.braille.write(output);
290 356
291 /** 357 // Display.
292 * Handles output to visual display.
293 */
294 handleDisplay: function() {
295 chrome.accessibilityPrivate.setFocusRing(this.locations_); 358 chrome.accessibilityPrivate.setFocusRing(this.locations_);
296 }, 359 },
297 360
298 /** 361 /**
299 * Renders the given range using optional context previous range and event 362 * Renders the given range using optional context previous range and event
300 * type. 363 * type.
301 * @param {!cursors.Range} range 364 * @param {!cursors.Range} range
302 * @param {cursors.Range} prevRange 365 * @param {cursors.Range} prevRange
303 * @param {chrome.automation.EventType|string} type 366 * @param {chrome.automation.EventType|string} type
367 * @param {!cvox.Spannable} buff Buffer to receive rendered output.
304 * @private 368 * @private
305 */ 369 */
306 render_: function(range, prevRange, type) { 370 render_: function(range, prevRange, type, buff) {
307 var buff = new cvox.Spannable();
308 var brailleBuff = new cvox.Spannable();
309 if (range.isSubNode()) 371 if (range.isSubNode())
310 this.subNode_(range, prevRange, type, buff); 372 this.subNode_(range, prevRange, type, buff);
311 else 373 else
312 this.range_(range, prevRange, type, buff); 374 this.range_(range, prevRange, type, buff);
313
314 this.formatOptions_.braille = true;
315 this.formatOptions_.location = false;
316 if (range.isSubNode())
317 this.subNode_(range, prevRange, type, brailleBuff);
318 else
319 this.range_(range, prevRange, type, brailleBuff);
320
321 this.buffer_ = buff;
322 this.brailleBuffer_ = brailleBuff;
323 }, 375 },
324 376
325 /** 377 /**
326 * Format the node given the format specifier. 378 * Format the node given the format specifier.
327 * @param {!chrome.automation.AutomationNode} node 379 * @param {!chrome.automation.AutomationNode} node
328 * @param {string|!Object} format The output format either specified as an 380 * @param {string|!Object} format The output format either specified as an
329 * output template string or a parsed output format tree. 381 * output template string or a parsed output format tree.
330 * @param {!Object=} opt_exclude A set of attributes to exclude. 382 * @param {!Object=} opt_exclude A set of attributes to exclude.
331 * @private 383 * @private
332 */ 384 */
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after
654 } 706 }
655 707
656 if (currentNode != root) 708 if (currentNode != root)
657 throw 'Unbalanced parenthesis.'; 709 throw 'Unbalanced parenthesis.';
658 710
659 return root; 711 return root;
660 } 712 }
661 }; 713 };
662 714
663 }); // goog.scope 715 }); // goog.scope
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698