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

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

Issue 2601333002: Update json_schema_compiler to handle the Automation extension API (Closed)
Patch Set: Fix select_to_speak Created 3 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 12 matching lines...) Expand all
23 goog.require('cvox.TtsCategory'); 23 goog.require('cvox.TtsCategory');
24 goog.require('cvox.ValueSelectionSpan'); 24 goog.require('cvox.ValueSelectionSpan');
25 goog.require('cvox.ValueSpan'); 25 goog.require('cvox.ValueSpan');
26 goog.require('goog.i18n.MessageFormat'); 26 goog.require('goog.i18n.MessageFormat');
27 27
28 goog.scope(function() { 28 goog.scope(function() {
29 var AutomationNode = chrome.automation.AutomationNode; 29 var AutomationNode = chrome.automation.AutomationNode;
30 var Dir = constants.Dir; 30 var Dir = constants.Dir;
31 var EventType = chrome.automation.EventType; 31 var EventType = chrome.automation.EventType;
32 var RoleType = chrome.automation.RoleType; 32 var RoleType = chrome.automation.RoleType;
33 var StateType = chrome.automation.StateType;
33 34
34 /** 35 /**
35 * An Output object formats a cursors.Range into speech, braille, or both 36 * An Output object formats a cursors.Range into speech, braille, or both
36 * representations. This is typically a |Spannable|. 37 * representations. This is typically a |Spannable|.
37 * 38 *
38 * The translation from Range to these output representations rely upon format 39 * The translation from Range to these output representations rely upon format
39 * rules which specify how to convert AutomationNode objects into annotated 40 * rules which specify how to convert AutomationNode objects into annotated
40 * strings. 41 * strings.
41 * The format of these rules is as follows. 42 * The format of these rules is as follows.
42 * 43 *
(...skipping 935 matching lines...) Expand 10 before | Expand all | Expand 10 after
978 if (prevRange && !prevRange.isValid()) 979 if (prevRange && !prevRange.isValid())
979 prevRange = null; 980 prevRange = null;
980 981
981 // Scan unique ancestors to get the value of |outputContextFirst|. 982 // Scan unique ancestors to get the value of |outputContextFirst|.
982 var parent = range.start.node; 983 var parent = range.start.node;
983 var prevParent = prevRange ? prevRange.start.node : parent; 984 var prevParent = prevRange ? prevRange.start.node : parent;
984 if (!parent || !prevParent) 985 if (!parent || !prevParent)
985 return; 986 return;
986 var uniqueAncestors = AutomationUtil.getUniqueAncestors(prevParent, parent); 987 var uniqueAncestors = AutomationUtil.getUniqueAncestors(prevParent, parent);
987 for (var i = 0; parent = uniqueAncestors[i]; i++) { 988 for (var i = 0; parent = uniqueAncestors[i]; i++) {
988 if (parent.role == RoleType.window) 989 if (parent.role == RoleType.WINDOW)
989 break; 990 break;
990 if (Output.ROLE_INFO_[parent.role] && 991 if (Output.ROLE_INFO_[parent.role] &&
991 Output.ROLE_INFO_[parent.role].outputContextFirst) { 992 Output.ROLE_INFO_[parent.role].outputContextFirst) {
992 this.outputContextFirst_ = true; 993 this.outputContextFirst_ = true;
993 break; 994 break;
994 } 995 }
995 } 996 }
996 997
997 if (range.isSubNode()) 998 if (range.isSubNode())
998 this.subNode_(range, prevRange, type, buff); 999 this.subNode_(range, prevRange, type, buff);
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1045 token = token.substring(0, token.length - 1); 1046 token = token.substring(0, token.length - 1);
1046 1047
1047 // Process token based on prefix. 1048 // Process token based on prefix.
1048 var prefix = token[0]; 1049 var prefix = token[0];
1049 token = token.slice(1); 1050 token = token.slice(1);
1050 1051
1051 // All possible tokens based on prefix. 1052 // All possible tokens based on prefix.
1052 if (prefix == '$') { 1053 if (prefix == '$') {
1053 if (token == 'value') { 1054 if (token == 'value') {
1054 var text = node.value; 1055 var text = node.value;
1055 if (!node.state.editable && node.name == text) 1056 if (!node.state[StateType.EDITABLE] && node.name == text)
1056 return; 1057 return;
1057 1058
1058 var selectedText = ''; 1059 var selectedText = '';
1059 if (text !== undefined) { 1060 if (text !== undefined) {
1060 if (node.textSelStart !== undefined) { 1061 if (node.textSelStart !== undefined) {
1061 options.annotation.push(new Output.SelectionSpan( 1062 options.annotation.push(new Output.SelectionSpan(
1062 node.textSelStart, 1063 node.textSelStart,
1063 node.textSelEnd)); 1064 node.textSelEnd));
1064 1065
1065 selectedText = 1066 selectedText =
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
1137 case 'mixed': 1138 case 'mixed':
1138 msg = 'aria_checked_mixed'; 1139 msg = 'aria_checked_mixed';
1139 break; 1140 break;
1140 case 'true': 1141 case 'true':
1141 msg = 'aria_checked_true'; 1142 msg = 'aria_checked_true';
1142 break; 1143 break;
1143 case 'false': 1144 case 'false':
1144 msg = 'aria_checked_false'; 1145 msg = 'aria_checked_false';
1145 break; 1146 break;
1146 default: 1147 default:
1147 msg = 1148 msg = node.state[StateType.CHECKED] ?
1148 node.state.checked ? 'aria_checked_true' : 'aria_checked_false'; 1149 'aria_checked_true' : 'aria_checked_false';
1149 } 1150 }
1150 this.format_(node, '@' + msg, buff); 1151 this.format_(node, '@' + msg, buff);
1151 } else if (token == 'state') { 1152 } else if (token == 'state') {
1152 Object.getOwnPropertyNames(node.state).forEach(function(s) { 1153 Object.getOwnPropertyNames(node.state).forEach(function(s) {
1153 var stateInfo = Output.STATE_INFO_[s]; 1154 var stateInfo = Output.STATE_INFO_[s];
1154 if (stateInfo && !stateInfo.isRoleSpecific && stateInfo.on) 1155 if (stateInfo && !stateInfo.isRoleSpecific && stateInfo.on)
1155 this.format_(node, '@' + stateInfo.on.msgId, buff); 1156 this.format_(node, '@' + stateInfo.on.msgId, buff);
1156 }.bind(this)); 1157 }.bind(this));
1157 } else if (token == 'find') { 1158 } else if (token == 'find') {
1158 // Find takes two arguments: JSON query string and format string. 1159 // Find takes two arguments: JSON query string and format string.
1159 if (tree.firstChild) { 1160 if (tree.firstChild) {
1160 var jsonQuery = tree.firstChild.value; 1161 var jsonQuery = tree.firstChild.value;
1161 node = node.find( 1162 node = node.find(
1162 /** @type {Object}*/(JSON.parse(jsonQuery))); 1163 /** @type {chrome.automation.FindParams}*/(
1164 JSON.parse(jsonQuery)));
1163 var formatString = tree.firstChild.nextSibling; 1165 var formatString = tree.firstChild.nextSibling;
1164 if (node) 1166 if (node)
1165 this.format_(node, formatString, buff); 1167 this.format_(node, formatString, buff);
1166 } 1168 }
1167 } else if (token == 'descendants') { 1169 } else if (token == 'descendants') {
1168 if (!node || AutomationPredicate.leafOrStaticText(node)) 1170 if (!node || AutomationPredicate.leafOrStaticText(node))
1169 return; 1171 return;
1170 1172
1171 // Construct a range to the leftmost and rightmost leaves. 1173 // Construct a range to the leftmost and rightmost leaves.
1172 var leftmost = AutomationUtil.findNodePre( 1174 var leftmost = AutomationUtil.findNodePre(
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after
1443 */ 1445 */
1444 ancestry_: function(node, prevNode, type, buff) { 1446 ancestry_: function(node, prevNode, type, buff) {
1445 // Expects |ancestors| to be ordered from root down to leaf. Outputs in 1447 // Expects |ancestors| to be ordered from root down to leaf. Outputs in
1446 // reverse; place context first nodes at the end. 1448 // reverse; place context first nodes at the end.
1447 function byContextFirst(ancestors) { 1449 function byContextFirst(ancestors) {
1448 var contextFirst = []; 1450 var contextFirst = [];
1449 var rest = []; 1451 var rest = [];
1450 for (i = 0; i < ancestors.length - 1; i++) { 1452 for (i = 0; i < ancestors.length - 1; i++) {
1451 var node = ancestors[i]; 1453 var node = ancestors[i];
1452 // Discard ancestors of deepest window. 1454 // Discard ancestors of deepest window.
1453 if (node.role == RoleType.window) { 1455 if (node.role == RoleType.WINDOW) {
1454 contextFirst = []; 1456 contextFirst = [];
1455 rest = []; 1457 rest = [];
1456 } 1458 }
1457 if ((Output.ROLE_INFO_[node.role] || {}).outputContextFirst) 1459 if ((Output.ROLE_INFO_[node.role] || {}).outputContextFirst)
1458 contextFirst.push(node); 1460 contextFirst.push(node);
1459 else 1461 else
1460 rest.push(node); 1462 rest.push(node);
1461 } 1463 }
1462 return rest.concat(contextFirst.reverse()); 1464 return rest.concat(contextFirst.reverse());
1463 } 1465 }
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
1607 } 1609 }
1608 } 1610 }
1609 1611
1610 if (this.outputContextFirst_) 1612 if (this.outputContextFirst_)
1611 this.ancestry_(node, prevNode, type, buff); 1613 this.ancestry_(node, prevNode, type, buff);
1612 var earcon = this.findEarcon_(node, prevNode); 1614 var earcon = this.findEarcon_(node, prevNode);
1613 if (earcon) 1615 if (earcon)
1614 options.annotation.push(earcon); 1616 options.annotation.push(earcon);
1615 var text = ''; 1617 var text = '';
1616 1618
1617 if (this.formatOptions_.braille && !node.state.editable) { 1619 if (this.formatOptions_.braille && !node.state[StateType.EDITABLE]) {
1618 // In braille, we almost always want to show the entire contents and 1620 // In braille, we almost always want to show the entire contents and
1619 // simply place the cursor under the SelectionSpan we set above. 1621 // simply place the cursor under the SelectionSpan we set above.
1620 text = range.start.getText(); 1622 text = range.start.getText();
1621 } else { 1623 } else {
1622 // This is output for speech or editable braille. 1624 // This is output for speech or editable braille.
1623 text = range.start.getText().substring(rangeStart, rangeEnd); 1625 text = range.start.getText().substring(rangeStart, rangeEnd);
1624 } 1626 }
1625 1627
1626 this.append_(buff, text, options); 1628 this.append_(buff, text, options);
1627 1629
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
1750 return result; 1752 return result;
1751 } 1753 }
1752 1754
1753 // Keep track of if there's an inline node associated with 1755 // Keep track of if there's an inline node associated with
1754 // |cur|. 1756 // |cur|.
1755 var hasInlineNode = cur.getSpansInstanceOf(Output.NodeSpan) 1757 var hasInlineNode = cur.getSpansInstanceOf(Output.NodeSpan)
1756 .some(function(s) { 1758 .some(function(s) {
1757 if (!s.node) 1759 if (!s.node)
1758 return false; 1760 return false;
1759 return s.node.display == 'inline' || 1761 return s.node.display == 'inline' ||
1760 s.node.role == RoleType.inlineTextBox; 1762 s.node.role == RoleType.INLINE_TEXT_BOX;
1761 }); 1763 });
1762 1764
1763 var isName = cur.hasSpan('name'); 1765 var isName = cur.hasSpan('name');
1764 1766
1765 // Now, decide whether we should include separators between the previous 1767 // Now, decide whether we should include separators between the previous
1766 // span and |cur|. 1768 // span and |cur|.
1767 // Never separate chunks without something already there at this point. 1769 // Never separate chunks without something already there at this point.
1768 1770
1769 // The only case where we know for certain that a separator is not needed 1771 // The only case where we know for certain that a separator is not needed
1770 // is when the previous and current values are in-lined and part of the 1772 // is when the previous and current values are in-lined and part of the
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
1847 /** 1849 /**
1848 * Gets the output buffer for braille. 1850 * Gets the output buffer for braille.
1849 * @return {!Spannable} 1851 * @return {!Spannable}
1850 */ 1852 */
1851 get brailleOutputForTest() { 1853 get brailleOutputForTest() {
1852 return this.mergeBraille_(this.brailleBuffer_); 1854 return this.mergeBraille_(this.brailleBuffer_);
1853 } 1855 }
1854 }; 1856 };
1855 1857
1856 }); // goog.scope 1858 }); // goog.scope
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698