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

Side by Side Diff: chrome/browser/resources/access_chromevox/chromevox/background/accessibility_api_handler.js

Issue 6254007: Adding ChromeVox as a component extensions (enabled only for ChromeOS, for no... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 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 | Annotate | Revision Log
Property Changes:
Added: svn:executable
+ *
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 /**
6 * @fileoverview Accesses Chrome's accessibility extension API and gives
7 * spoken feedback for events that happen in the "Chrome of Chrome".
8 */
9
10 goog.provide('cvox.ChromeVoxAccessibilityApiHandler');
11
12 goog.require('cvox.AbstractEarcons');
13 goog.require('cvox.AbstractEarconsManager');
14 goog.require('cvox.AbstractTtsManager');
15 goog.require('cvox.ChromeVoxEditableTextBase');
16
17 /**
18 * Class that adds listeners and handles events from the accessibility API.
19 */
20 cvox.ChromeVoxAccessibilityApiHandler = function() {
21 };
22
23 /**
24 * The object used to play earcons.
25 * @type Object
26 */
27 cvox.ChromeVoxAccessibilityApiHandler.ttsManager = null;
28
29 /**
30 * The object used to manage speech.
31 * @type Object
32 */
33 cvox.ChromeVoxAccessibilityApiHandler.earconsManager = null;
34
35 /**
36 * The object that can describe changes and cursor movement in a generic
37 * editable text field.
38 * @type Object
39 */
40 cvox.ChromeVoxAccessibilityApiHandler.editableTextHandler = null;
41
42 /**
43 * Initialize the accessibility API Handler.
44 * @param {Object} ttsManager The TTS manager to use for speaking.
45 * @param {Object} earconsManager The earcons manager to use for playing
46 * earcons.
47 */
48 cvox.ChromeVoxAccessibilityApiHandler.init = function(ttsManager,
49 earconsManager) {
50 cvox.ChromeVoxAccessibilityApiHandler.ttsManager = ttsManager;
51 cvox.ChromeVoxAccessibilityApiHandler.earconsManager = earconsManager;
52 try {
53 chrome.experimental.accessibility.setAccessibilityEnabled(true);
54 cvox.ChromeVoxAccessibilityApiHandler.addEventListeners();
55 } catch (err) {
56 console.log('Error trying to access accessibility extension api.');
57 }
58 };
59
60 /**
61 * Adds event listeners.
62 */
63 cvox.ChromeVoxAccessibilityApiHandler.addEventListeners = function() {
64 var accessibility = chrome.experimental.accessibility;
65
66 chrome.tabs.onCreated.addListener(function(tab) {
67 var tts = cvox.ChromeVoxAccessibilityApiHandler.ttsManager;
68 var title = tab.title ? tab.title : tab.url;
69 tts.speak(title + ', tab created.', 0, {});
70 var earcons = cvox.ChromeVoxAccessibilityApiHandler.earconsManager;
71 earcons.playEarcon(cvox.AbstractEarcons.OBJECT_OPEN);
72 });
73
74 chrome.tabs.onRemoved.addListener(function(tab) {
75 var earcons = cvox.ChromeVoxAccessibilityApiHandler.earconsManager;
76 earcons.playEarcon(cvox.AbstractEarcons.OBJECT_CLOSE);
77 });
78
79 chrome.tabs.onSelectionChanged.addListener(function(tabId, selectInfo) {
80 chrome.tabs.get(tabId, function(tab) {
81 var tts = cvox.ChromeVoxAccessibilityApiHandler.ttsManager;
82 var title = tab.title ? tab.title : tab.url;
83 tts.speak(title + ', tab.', 0, {});
84 var earcons = cvox.ChromeVoxAccessibilityApiHandler.earconsManager;
85 earcons.playEarcon(cvox.AbstractEarcons.OBJECT_SELECT);
86 });
87 });
88
89 chrome.tabs.onUpdated.addListener(function(tabId, selectInfo) {
90 chrome.tabs.get(tabId, function(tab) {
91 var earcons = cvox.ChromeVoxAccessibilityApiHandler.earconsManager;
92 if (tab.status == 'loading') {
93 earcons.playEarcon(cvox.AbstractEarcons.BUSY_PROGRESS_LOOP);
94 } else {
95 earcons.playEarcon(cvox.AbstractEarcons.TASK_SUCCESS);
96 }
97 });
98 });
99
100 chrome.experimental.accessibility.onWindowOpened.addListener(function(win) {
101 var tts = cvox.ChromeVoxAccessibilityApiHandler.ttsManager;
102 tts.speak(win.name + ', window opened.', 0, {});
103 var earcons = cvox.ChromeVoxAccessibilityApiHandler.earconsManager;
104 earcons.playEarcon(cvox.AbstractEarcons.OBJECT_OPEN);
105 });
106
107 chrome.experimental.accessibility.onWindowClosed.addListener(function(win) {
108 var tts = cvox.ChromeVoxAccessibilityApiHandler.ttsManager;
109 tts.speak(win.name + ', window closed.', 0, {});
110 var earcons = cvox.ChromeVoxAccessibilityApiHandler.earconsManager;
111 earcons.playEarcon(cvox.AbstractEarcons.OBJECT_CLOSE);
112 });
113
114 chrome.experimental.accessibility.onMenuOpened.addListener(function(menu) {
115 var tts = cvox.ChromeVoxAccessibilityApiHandler.ttsManager;
116 tts.speak(menu.name + ', menu opened.', 0, {});
117 var earcons = cvox.ChromeVoxAccessibilityApiHandler.earconsManager;
118 earcons.playEarcon(cvox.AbstractEarcons.OBJECT_OPEN);
119 });
120
121 chrome.experimental.accessibility.onMenuClosed.addListener(function(menu) {
122 var tts = cvox.ChromeVoxAccessibilityApiHandler.ttsManager;
123 tts.speak(menu.name + ', menu closed.', 0, {});
124 var earcons = cvox.ChromeVoxAccessibilityApiHandler.earconsManager;
125 earcons.playEarcon(cvox.AbstractEarcons.OBJECT_CLOSE);
126 });
127
128 chrome.experimental.accessibility.onControlFocused.addListener(
129 /**
130 * @param {AccessibilityObject} ctl The focused control.
131 */
132 function(ctl) {
133 var tts = cvox.ChromeVoxAccessibilityApiHandler.ttsManager;
134 if (ctl.type == 'textbox') {
135 cvox.ChromeVoxAccessibilityApiHandler.trimWhitespace(ctl);
136 cvox.ChromeVoxAccessibilityApiHandler.editableTextHandler =
137 new cvox.ChromeVoxEditableTextBase(
138 ctl.details.value,
139 ctl.details.selectionStart,
140 ctl.details.selectionEnd,
141 tts);
142 } else {
143 cvox.ChromeVoxAccessibilityApiHandler.editableTextHandler = null;
144 }
145
146 var description = cvox.ChromeVoxAccessibilityApiHandler.describe(ctl,
147 false);
148 tts.speak(description.utterance, 0, {});
149 if (description.earcon) {
150 var earcons =
151 cvox.ChromeVoxAccessibilityApiHandler.earconsManager;
152 earcons.playEarcon(description.earcon);
153 }
154 });
155
156 chrome.experimental.accessibility.onControlAction.addListener(function(ctl) {
157 var tts = cvox.ChromeVoxAccessibilityApiHandler.ttsManager;
158 var description = cvox.ChromeVoxAccessibilityApiHandler.describe(ctl,
159 true);
160 tts.speak(description.utterance, 0, {});
161 if (description.earcon) {
162 var earcons = cvox.ChromeVoxAccessibilityApiHandler.earconsManager;
163 earcons.playEarcon(description.earcon);
164 }
165 });
166
167 chrome.experimental.accessibility.onTextChanged.addListener(function(ctl) {
168 if (cvox.ChromeVoxAccessibilityApiHandler.editableTextHandler) {
169 cvox.ChromeVoxAccessibilityApiHandler.trimWhitespace(ctl);
170 cvox.ChromeVoxAccessibilityApiHandler.editableTextHandler.changed(
171 ctl.details.value,
172 ctl.details.selectionStart,
173 ctl.details.selectionEnd);
174 }
175 });
176 };
177
178 /**
179 * Given a text control received from the accessibility api, trim any
180 * leading or trailing whitespace from control.details.value and from
181 * selectionStart and selectionEnd.
182 * @param {Object} control The text control object.
183 */
184 cvox.ChromeVoxAccessibilityApiHandler.trimWhitespace = function(control) {
185 var d = control.details;
186 var prefix = new RegExp(/^[\s\u200b]+/).exec(d.value);
187 var suffix = new RegExp(/[\s\u200b]+$/).exec(d.value);
188 var prefixLen = prefix ? prefix.length : 0;
189 var suffixLen = suffix ? suffix.length : 0;
190 d.value = d.value.substr(prefix, d.value.length - prefixLen - suffixLen);
191 d.selectionStart -= prefixLen;
192 d.selectionEnd -= prefixLen;
193 if (d.selectionEnd > d.value.length) {
194 d.selectionEnd = d.value.length;
195 }
196 };
197
198 /**
199 * Given a control received from the accessibility api, determine an
200 * utterance to speak and an earcon to play to describe it.
201 * @param {Object} control The control that had an action performed on it.
202 * @param {boolean} isSelect True if the action is a select action,
203 * otherwise it's a focus action.
204 * @return {Object} An object containing a string field |utterance| and
205 * earcon |earcon|.
206 */
207 cvox.ChromeVoxAccessibilityApiHandler.describe = function(control,
208 isSelect) {
209 var s = '';
210 var earcon = undefined;
211 var name = control.name.replace(/[_&]+/g, '').replace('...', '');
212 switch (control.type) {
213 case 'checkbox':
214 s += name;
215 if (control.details.isChecked) {
216 earcon = cvox.AbstractEarcons.CHECK_ON;
217 s += ', checkbox checked';
218 } else {
219 earcon = cvox.AbstractEarcons.CHECK_OFF;
220 s += ', checkbox not checked';
221 }
222 break;
223 case 'radiobutton':
224 s += name;
225 if (control.details.isChecked) {
226 earcon = cvox.AbstractEarcons.CHECK_ON;
227 s += ', radio button selected';
228 } else {
229 earcon = cvox.AbstractEarcons.CHECK_OFF;
230 s += ', radio button unselected';
231 }
232 break;
233 case 'menu':
234 s += name + ', menu';
235 break;
236 case 'menuitem':
237 s += name + ', menu item';
238 if (control.details.hasSubmenu) {
239 s += ', with submenu';
240 }
241 break;
242 case 'window':
243 s += name + ', window';
244 break;
245 case 'textbox':
246 earcon = cvox.AbstractEarcons.EDITABLE_TEXT;
247 s += control.details.value;
248 if (name != '') {
249 s += ', ' + name;
250 }
251 s += ', text box';
252 break;
253 case 'button':
254 earcon = cvox.AbstractEarcons.BUTTON;
255 s += name + ', button';
256 break;
257 case 'combobox':
258 earcon = cvox.AbstractEarcons.LISTBOX;
259 s += control.details.value;
260 if (name != '') {
261 s += ', ' + name;
262 }
263 s += ', combo box';
264 break;
265 case 'listbox':
266 earcon = cvox.AbstractEarcons.LISTBOX;
267 s += control.details.value;
268 if (name != '') {
269 s += ', ' + name;
270 }
271 s += ', list box';
272 break;
273 case 'link':
274 earcon = cvox.AbstractEarcons.LINK;
275 s += name + ', link';
276 break;
277 case 'tab':
278 s += name + ', tab';
279 break;
280
281 default:
282 s += name + ', ' + control.type;
283 }
284
285 if (isSelect) {
286 s += ', selected';
287 }
288 try {
289 if (control.details.itemCount >= 0) {
290 s += ', ' + (control.details.itemIndex + 1) +
291 ' of ' + control.details.itemCount;
292 }
293 } catch (err) {
294 }
295
296 s += '.';
297
298 var description = {};
299 description.utterance = s;
300 description.earcon = earcon;
301 return description;
302 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698