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

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

Issue 816093002: Support alert nodes by introducing $descendant and !ttsProps. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@lkcr
Patch Set: Simplify Created 5 years, 10 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
« no previous file with comments | « chrome/browser/resources/chromeos/chromevox/cvox2/background/automation_predicate.js ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
44 */ 44 */
45 Output = function() { 45 Output = function() {
46 // TODO(dtseng): Include braille specific rules. 46 // TODO(dtseng): Include braille specific rules.
47 /** @type {!cvox.Spannable} */ 47 /** @type {!cvox.Spannable} */
48 this.buffer_ = new cvox.Spannable(); 48 this.buffer_ = new cvox.Spannable();
49 /** @type {!cvox.Spannable} */ 49 /** @type {!cvox.Spannable} */
50 this.brailleBuffer_ = new cvox.Spannable(); 50 this.brailleBuffer_ = new cvox.Spannable();
51 /** @type {!Array.<Object>} */ 51 /** @type {!Array.<Object>} */
52 this.locations_ = []; 52 this.locations_ = [];
53 /** @type {function()} */ 53 /** @type {function()} */
54 this.speechStartCallback_ = function() {}; 54 this.speechStartCallback_;
55 /** @type {function()} */ 55 /** @type {function()} */
56 this.speechEndCallback_ = function() {}; 56 this.speechEndCallback_;
57 /** @type {function()} */ 57 /** @type {function()} */
58 this.speechInterruptedCallback_ = function() {}; 58 this.speechInterruptedCallback_;
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 /**
67 * Speech properties to apply to the entire output.
68 * @type {!Object.<string, *>}
69 */
70 this.speechProperties_ = {};
65 }; 71 };
66 72
67 /** 73 /**
68 * Delimiter to use between output values. 74 * Delimiter to use between output values.
69 * @type {string} 75 * @type {string}
70 */ 76 */
71 Output.SPACE = ' '; 77 Output.SPACE = ' ';
72 78
73 /** 79 /**
74 * Rules specifying format of AutomationNodes for output. 80 * Rules specifying format of AutomationNodes for output.
75 * @type {!Object.<string, Object.<string, Object.<string, string>>>} 81 * @type {!Object.<string, Object.<string, Object.<string, string>>>}
76 */ 82 */
77 Output.RULES = { 83 Output.RULES = {
78 navigate: { 84 navigate: {
79 'default': { 85 'default': {
80 speak: '$name $role $value', 86 speak: '$name $role $value',
81 braille: '' 87 braille: ''
82 }, 88 },
83 alert: { 89 alert: {
84 speak: '@aria_role_alert $name $earcon(ALERT_NONMODAL)' 90 speak: '!doNotInterrupt' +
dmazzoni 2015/02/04 08:50:16 is there supposed to be a space after the !doNotIn
David Tseng 2015/02/04 16:57:13 Good catch! The parser splits expressions on space
91 '@aria_role_alert $name $earcon(ALERT_NONMODAL) $descendants'
85 }, 92 },
86 button: { 93 button: {
87 speak: '$name $earcon(BUTTON, @tag_button)' 94 speak: '$name $earcon(BUTTON, @tag_button)'
88 }, 95 },
89 checkBox: { 96 checkBox: {
90 speak: '$or($checked, @describe_checkbox_checked($name), ' + 97 speak: '$or($checked, @describe_checkbox_checked($name), ' +
91 '@describe_checkbox_unchecked($name)) ' + 98 '@describe_checkbox_unchecked($name)) ' +
92 '$or($checked, ' + 99 '$or($checked, ' +
93 '$earcon(CHECK_ON, @input_type_checkbox), ' + 100 '$earcon(CHECK_ON, @input_type_checkbox), ' +
94 '$earcon(CHECK_OFF, @input_type_checkbox))' 101 '$earcon(CHECK_OFF, @input_type_checkbox))'
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
300 307
301 /** 308 /**
302 * Executes all specified output. 309 * Executes all specified output.
303 */ 310 */
304 go: function() { 311 go: function() {
305 // Speech. 312 // Speech.
306 var buff = this.buffer_; 313 var buff = this.buffer_;
307 314
308 var onEvent = function(evt) { 315 var onEvent = function(evt) {
309 switch (evt.type) { 316 switch (evt.type) {
310 case 'start': this.speechStartCallback_(); break; 317 case 'start':
311 case 'end': this.speechEndCallback_(); break; 318 this.speechStartCallback_();
312 case 'interrupted': this.speechInterruptedCallback_(); break; 319 break;
320 case 'end':
321 this.speechEndCallback_();
322 break;
323 case 'interrupted':
324 this.speechInterruptedCallback_ && this.speechInterruptedCallback_();
325 break;
313 } 326 }
314 }.bind(this); 327 }.bind(this);
315 328
316 if (buff.toString()) { 329 if (buff.toString()) {
330 if (this.speechStartCallback_ ||
331 this.speechEndCallback_ ||
332 this.speechInterruptedCallback_)
333 this.speechProperties_['onEvent'] = onEvent;
334
317 cvox.ChromeVox.tts.speak( 335 cvox.ChromeVox.tts.speak(
318 buff.toString(), cvox.QueueMode.FLUSH, {onEvent: onEvent}); 336 buff.toString(), cvox.QueueMode.FLUSH, this.speechProperties_);
319 } 337 }
320 338
321 var actions = buff.getSpansInstanceOf(Output.Action); 339 var actions = buff.getSpansInstanceOf(Output.Action);
322 if (actions) { 340 if (actions) {
323 actions.forEach(function(a) { 341 actions.forEach(function(a) {
324 a.run(); 342 a.run();
325 }); 343 });
326 } 344 }
327 345
328 // Braille. 346 // Braille.
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
450 } else if (token == 'find') { 468 } else if (token == 'find') {
451 // Find takes two arguments: JSON query string and format string. 469 // Find takes two arguments: JSON query string and format string.
452 if (tree.firstChild) { 470 if (tree.firstChild) {
453 var jsonQuery = tree.firstChild.value; 471 var jsonQuery = tree.firstChild.value;
454 node = node.find( 472 node = node.find(
455 /** @type {Object}*/(JSON.parse(jsonQuery))); 473 /** @type {Object}*/(JSON.parse(jsonQuery)));
456 var formatString = tree.firstChild.nextSibling; 474 var formatString = tree.firstChild.nextSibling;
457 if (node) 475 if (node)
458 this.format_(node, formatString, buff); 476 this.format_(node, formatString, buff);
459 } 477 }
478 } else if (token == 'descendants') {
479 // Construct a range to the leftmost and rightmost leaves.
480 var leftmost = AutomationUtil.findNodePre(
481 node, Dir.FORWARD, AutomationPredicate.leaf);
482 var rightmost = AutomationUtil.findNodePre(
483 node, Dir.BACKWARD, AutomationPredicate.leaf);
484 if (!leftmost || !rightmost)
485 return;
486
487 var subrange = new cursors.Range(
488 new cursors.Cursor(leftmost, 0),
489 new cursors.Cursor(rightmost, 0));
490 this.range_(subrange, null, 'navigate', buff);
460 } else if (node.attributes[token]) { 491 } else if (node.attributes[token]) {
461 this.addToSpannable_(buff, node.attributes[token], options); 492 this.addToSpannable_(buff, node.attributes[token], options);
462 } else if (node.state[token]) { 493 } else if (node.state[token]) {
463 this.addToSpannable_(buff, token, options); 494 this.addToSpannable_(buff, token, options);
464 } else if (tree.firstChild) { 495 } else if (tree.firstChild) {
465 // Custom functions. 496 // Custom functions.
466 if (token == 'or') { 497 if (token == 'or') {
467 var cond = tree.firstChild; 498 var cond = tree.firstChild;
468 var attrib = cond.value.slice(1); 499 var attrib = cond.value.slice(1);
469 if (node.attributes[attrib] || node.state[attrib]) 500 if (node.attributes[attrib] || node.state[attrib])
(...skipping 29 matching lines...) Expand all
499 } 530 }
500 var msg = cvox.ChromeVox.msgs.getMsg(msgId, msgArgs); 531 var msg = cvox.ChromeVox.msgs.getMsg(msgId, msgArgs);
501 try { 532 try {
502 if (this.formatOptions_.braille) 533 if (this.formatOptions_.braille)
503 msg = cvox.ChromeVox.msgs.getMsg(msgId + '_brl', msgArgs) || msg; 534 msg = cvox.ChromeVox.msgs.getMsg(msgId + '_brl', msgArgs) || msg;
504 } catch(e) {} 535 } catch(e) {}
505 536
506 if (msg) { 537 if (msg) {
507 this.addToSpannable_(buff, msg, options); 538 this.addToSpannable_(buff, msg, options);
508 } 539 }
540 } else if (prefix == '!') {
541 this.speechProperties_[token] = true;
509 } 542 }
510 }.bind(this)); 543 }.bind(this));
511 }, 544 },
512 545
513 /** 546 /**
514 * @param {!cursors.Range} range 547 * @param {!cursors.Range} range
515 * @param {cursors.Range} prevRange 548 * @param {cursors.Range} prevRange
516 * @param {chrome.automation.EventType|string} type 549 * @param {chrome.automation.EventType|string} type
517 * @param {!cvox.Spannable} rangeBuff 550 * @param {!cvox.Spannable} rangeBuff
518 * @private 551 * @private
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
706 } 739 }
707 740
708 if (currentNode != root) 741 if (currentNode != root)
709 throw 'Unbalanced parenthesis.'; 742 throw 'Unbalanced parenthesis.';
710 743
711 return root; 744 return root;
712 } 745 }
713 }; 746 };
714 747
715 }); // goog.scope 748 }); // goog.scope
OLDNEW
« no previous file with comments | « chrome/browser/resources/chromeos/chromevox/cvox2/background/automation_predicate.js ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698