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

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

Issue 2445003002: Reland: Make ChromeVox Next the default ChromeVox experience (Closed)
Patch Set: speculative fixes Created 4 years, 1 month 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 ChromeVox options page. 6 * @fileoverview ChromeVox options page.
7 * 7 *
8 */ 8 */
9 9
10 goog.provide('cvox.OptionsPage'); 10 goog.provide('cvox.OptionsPage');
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
54 }; 54 };
55 55
56 /** 56 /**
57 * Initialize the options page by setting the current value of all prefs, 57 * Initialize the options page by setting the current value of all prefs,
58 * building the key bindings table, and adding event listeners. 58 * building the key bindings table, and adding event listeners.
59 * @suppress {missingProperties} Property prefs never defined on Window 59 * @suppress {missingProperties} Property prefs never defined on Window
60 */ 60 */
61 cvox.OptionsPage.init = function() { 61 cvox.OptionsPage.init = function() {
62 cvox.OptionsPage.prefs = chrome.extension.getBackgroundPage().prefs; 62 cvox.OptionsPage.prefs = chrome.extension.getBackgroundPage().prefs;
63 cvox.OptionsPage.populateKeyMapSelect(); 63 cvox.OptionsPage.populateKeyMapSelect();
64 cvox.OptionsPage.addKeys();
65 cvox.OptionsPage.populateVoicesSelect(); 64 cvox.OptionsPage.populateVoicesSelect();
66 cvox.BrailleTable.getAll(function(tables) { 65 cvox.BrailleTable.getAll(function(tables) {
67 /** @type {!Array<cvox.BrailleTable.Table>} */ 66 /** @type {!Array<cvox.BrailleTable.Table>} */
68 cvox.OptionsPage.brailleTables = tables; 67 cvox.OptionsPage.brailleTables = tables;
69 cvox.OptionsPage.populateBrailleTablesSelect(); 68 cvox.OptionsPage.populateBrailleTablesSelect();
70 }); 69 });
71 chrome.storage.local.get({'brailleWordWrap': true}, function(items) { 70 chrome.storage.local.get({'brailleWordWrap': true}, function(items) {
72 $('brailleWordWrap').checked = items.brailleWordWrap; 71 $('brailleWordWrap').checked = items.brailleWordWrap;
73 }); 72 });
74 73
(...skipping 12 matching lines...) Expand all
87 } 86 }
88 }); 87 });
89 88
90 $('selectKeys').addEventListener( 89 $('selectKeys').addEventListener(
91 'click', cvox.OptionsPage.reset, false); 90 'click', cvox.OptionsPage.reset, false);
92 91
93 if (cvox.PlatformUtil.matchesPlatform(cvox.PlatformFilter.WML)) { 92 if (cvox.PlatformUtil.matchesPlatform(cvox.PlatformFilter.WML)) {
94 $('version').textContent = 93 $('version').textContent =
95 chrome.app.getDetails().version; 94 chrome.app.getDetails().version;
96 } 95 }
97
98 $('useNext').addEventListener('change', function(evt) {
99 var checked = evt.target.checked;
100 var background =
101 chrome.extension.getBackgroundPage().ChromeVoxState.instance;
102 background.toggleNext(checked);
103 }, true);
104 }; 96 };
105 97
106 /** 98 /**
107 * Update the value of controls to match the current preferences. 99 * Update the value of controls to match the current preferences.
108 * This happens if the user presses a key in a tab that changes a 100 * This happens if the user presses a key in a tab that changes a
109 * pref. 101 * pref.
110 */ 102 */
111 cvox.OptionsPage.update = function() { 103 cvox.OptionsPage.update = function() {
112 var prefs = cvox.OptionsPage.prefs.getPrefs(); 104 var prefs = cvox.OptionsPage.prefs.getPrefs();
113 for (var key in prefs) { 105 for (var key in prefs) {
(...skipping 20 matching lines...) Expand all
134 if (cvox.OptionsPage.prefs.getPrefs()['currentKeyMap'] == id) { 126 if (cvox.OptionsPage.prefs.getPrefs()['currentKeyMap'] == id) {
135 option.setAttribute('selected', ''); 127 option.setAttribute('selected', '');
136 } 128 }
137 select.appendChild(option); 129 select.appendChild(option);
138 } 130 }
139 131
140 select.addEventListener('change', cvox.OptionsPage.reset, true); 132 select.addEventListener('change', cvox.OptionsPage.reset, true);
141 }; 133 };
142 134
143 /** 135 /**
144 * Add the input elements for the key bindings to the container element
145 * in the page. They're sorted in order of description.
146 */
147 cvox.OptionsPage.addKeys = function() {
148 var container = $('keysContainer');
149 var keyMap = cvox.OptionsPage.prefs.getKeyMap();
150
151 cvox.OptionsPage.prevTime = new Date().getTime();
152 cvox.OptionsPage.keyCount = 0;
153 container.addEventListener('keypress', goog.bind(function(evt) {
154 if (evt.target.id == 'cvoxKey') {
155 return;
156 }
157 this.keyCount++;
158 var currentTime = new Date().getTime();
159 if (currentTime - this.prevTime > 1000 || this.keyCount > 2) {
160 if (document.activeElement.id == 'toggleKeyPrefix') {
161 this.keySequence = new cvox.KeySequence(evt, false);
162 this.keySequence.keys['ctrlKey'][0] = true;
163 } else {
164 this.keySequence = new cvox.KeySequence(evt, true);
165 }
166
167 this.keyCount = 1;
168 } else {
169 this.keySequence.addKeyEvent(evt);
170 }
171
172 var keySeqStr = cvox.KeyUtil.keySequenceToString(this.keySequence, true);
173 var announce = keySeqStr.replace(/\+/g,
174 ' ' + Msgs.getMsg('then') + ' ');
175 announce = announce.replace(/>/g,
176 ' ' + Msgs.getMsg('followed_by') + ' ');
177 announce = announce.replace('Cvox',
178 ' ' + Msgs.getMsg('modifier_key') + ' ');
179
180 // TODO(dtseng): Only basic conflict detection; it does not speak the
181 // conflicting command. Nor does it detect prefix conflicts like Cvox+L vs
182 // Cvox+L>L.
183 if (cvox.OptionsPage.prefs.setKey(document.activeElement.id,
184 this.keySequence)) {
185 document.activeElement.value = keySeqStr;
186 } else {
187 announce = Msgs.getMsg('key_conflict', [announce]);
188 }
189 cvox.OptionsPage.speak(announce, cvox.QueueMode.QUEUE);
190 this.prevTime = currentTime;
191
192 evt.preventDefault();
193 evt.stopPropagation();
194 }, cvox.OptionsPage), true);
195
196 var categories = cvox.CommandStore.categories();
197 for (var i = 0; i < categories.length; i++) {
198 // Braille bindings can't be customized, so don't include them.
199 if (categories[i] == 'braille') {
200 continue;
201 }
202 var headerElement = document.createElement('h3');
203 headerElement.className = 'i18n';
204 headerElement.setAttribute('msgid', categories[i]);
205 headerElement.id = categories[i];
206 container.appendChild(headerElement);
207 var commands = cvox.CommandStore.commandsForCategory(categories[i]);
208 for (var j = 0; j < commands.length; j++) {
209 var command = commands[j];
210 // TODO: Someday we may want to have more than one key
211 // mapped to a command, so we'll need to figure out how to display
212 // that. For now, just take the first key.
213 var keySeqObj = keyMap.keyForCommand(command)[0];
214
215 // Explicitly skip toggleChromeVox in ChromeOS.
216 if (command == 'toggleChromeVox' &&
217 cvox.PlatformUtil.matchesPlatform(cvox.PlatformFilter.CHROMEOS)) {
218 continue;
219 }
220
221 var inputElement = document.createElement('input');
222 inputElement.type = 'text';
223 inputElement.className = 'key active-key';
224 inputElement.id = command;
225
226 var displayedCombo;
227 if (keySeqObj != null) {
228 displayedCombo = cvox.KeyUtil.keySequenceToString(keySeqObj, true);
229 } else {
230 displayedCombo = '';
231 }
232 inputElement.value = displayedCombo;
233
234 // Don't allow the user to change the sticky mode or stop speaking key.
235 if (command == 'toggleStickyMode' || command == 'stopSpeech') {
236 inputElement.disabled = true;
237 }
238 var message = cvox.CommandStore.messageForCommand(command);
239 if (!message) {
240 // TODO(dtseng): missing message id's.
241 message = command;
242 }
243
244 var labelElement = document.createElement('label');
245 labelElement.className = 'i18n';
246 labelElement.setAttribute('msgid', message);
247 labelElement.setAttribute('for', inputElement.id);
248
249 var divElement = document.createElement('div');
250 divElement.className = 'key-container';
251 container.appendChild(divElement);
252 divElement.appendChild(inputElement);
253 divElement.appendChild(labelElement);
254 }
255 var brElement = document.createElement('br');
256 container.appendChild(brElement);
257 }
258
259 if ($('cvoxKey') == null) {
260 // Add the cvox key field
261 var inputElement = document.createElement('input');
262 inputElement.type = 'text';
263 inputElement.className = 'key';
264 inputElement.id = 'cvoxKey';
265
266 var labelElement = document.createElement('label');
267 labelElement.className = 'i18n';
268 labelElement.setAttribute('msgid', 'options_cvox_modifier_key');
269 labelElement.setAttribute('for', 'cvoxKey');
270
271 var modifierSectionSibling =
272 $('modifier_keys').nextSibling;
273 var modifierSectionParent = modifierSectionSibling.parentNode;
274 modifierSectionParent.insertBefore(labelElement, modifierSectionSibling);
275 modifierSectionParent.insertBefore(inputElement, labelElement);
276 var cvoxKey = $('cvoxKey');
277 cvoxKey.value = localStorage['cvoxKey'];
278
279 cvoxKey.addEventListener('keydown', function(evt) {
280 if (!this.modifierSeq_) {
281 this.modifierCount_ = 0;
282 this.modifierSeq_ = new cvox.KeySequence(evt, false);
283 } else {
284 this.modifierSeq_.addKeyEvent(evt);
285 }
286
287 // Never allow non-modified keys.
288 if (!this.modifierSeq_.isAnyModifierActive()) {
289 // Indicate error and instructions excluding tab.
290 if (evt.keyCode != 9) {
291 cvox.OptionsPage.speak(
292 Msgs.getMsg('modifier_entry_error'),
293 cvox.QueueMode.FLUSH, {});
294 }
295 this.modifierSeq_ = null;
296 } else {
297 this.modifierCount_++;
298 }
299
300 // Don't trap tab or shift.
301 if (!evt.shiftKey && evt.keyCode != 9) {
302 evt.preventDefault();
303 evt.stopPropagation();
304 }
305 }, true);
306
307 cvoxKey.addEventListener('keyup', function(evt) {
308 if (this.modifierSeq_) {
309 this.modifierCount_--;
310
311 if (this.modifierCount_ == 0) {
312 var modifierStr =
313 cvox.KeyUtil.keySequenceToString(this.modifierSeq_, true, true);
314 evt.target.value = modifierStr;
315 cvox.OptionsPage.speak(
316 Msgs.getMsg('modifier_entry_set', [modifierStr]),
317 cvox.QueueMode.QUEUE);
318 localStorage['cvoxKey'] = modifierStr;
319 this.modifierSeq_ = null;
320 }
321 evt.preventDefault();
322 evt.stopPropagation();
323 }
324 }, true);
325 }
326 };
327
328 /**
329 * Populates the voices select with options. 136 * Populates the voices select with options.
330 */ 137 */
331 cvox.OptionsPage.populateVoicesSelect = function() { 138 cvox.OptionsPage.populateVoicesSelect = function() {
332 var select = $('voices'); 139 var select = $('voices');
333 140
334 function setVoiceList() { 141 function setVoiceList() {
335 var selectedVoiceName = 142 var selectedVoiceName =
336 chrome.extension.getBackgroundPage()['getCurrentVoice'](); 143 chrome.extension.getBackgroundPage()['getCurrentVoice']();
337 chrome.tts.getVoices(function(voices) { 144 chrome.tts.getVoices(function(voices) {
338 select.innerHTML = ''; 145 select.innerHTML = '';
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
523 var selectKeyMap = $('cvox_keymaps'); 330 var selectKeyMap = $('cvox_keymaps');
524 var id = selectKeyMap.options[selectKeyMap.selectedIndex].id; 331 var id = selectKeyMap.options[selectKeyMap.selectedIndex].id;
525 332
526 var msgs = Msgs; 333 var msgs = Msgs;
527 var announce = cvox.OptionsPage.prefs.getPrefs()['currentKeyMap'] == id ? 334 var announce = cvox.OptionsPage.prefs.getPrefs()['currentKeyMap'] == id ?
528 msgs.getMsg('keymap_reset', [msgs.getMsg(id)]) : 335 msgs.getMsg('keymap_reset', [msgs.getMsg(id)]) :
529 msgs.getMsg('keymap_switch', [msgs.getMsg(id)]); 336 msgs.getMsg('keymap_switch', [msgs.getMsg(id)]);
530 cvox.OptionsPage.updateStatus_(announce); 337 cvox.OptionsPage.updateStatus_(announce);
531 338
532 cvox.OptionsPage.prefs.switchToKeyMap(id); 339 cvox.OptionsPage.prefs.switchToKeyMap(id);
533 $('keysContainer').innerHTML = '';
534 cvox.OptionsPage.addKeys();
535 Msgs.addTranslatedMessagesToDom(document); 340 Msgs.addTranslatedMessagesToDom(document);
536 }; 341 };
537 342
538 /** 343 /**
539 * Updates the status live region. 344 * Updates the status live region.
540 * @param {string} status The new status. 345 * @param {string} status The new status.
541 * @private 346 * @private
542 */ 347 */
543 cvox.OptionsPage.updateStatus_ = function(status) { 348 cvox.OptionsPage.updateStatus_ = function(status) {
544 $('status').innerText = status; 349 $('status').innerText = status;
545 }; 350 };
546 351
547 352
548 /** 353 /**
549 * Hides all elements not matching the current platform. 354 * Hides all elements not matching the current platform.
550 */ 355 */
551 cvox.OptionsPage.hidePlatformSpecifics = function() { 356 cvox.OptionsPage.hidePlatformSpecifics = function() {
552 if (!cvox.ChromeVox.isChromeOS) { 357 if (!cvox.ChromeVox.isChromeOS) {
553 var elements = document.body.querySelectorAll('.chromeos'); 358 var elements = document.body.querySelectorAll('.chromeos');
554 for (var i = 0, el; el = elements[i]; i++) { 359 for (var i = 0, el; el = elements[i]; i++) {
555 el.setAttribute('aria-hidden', 'true'); 360 el.setAttribute('aria-hidden', 'true');
556 el.style.display = 'none'; 361 el.style.display = 'none';
557 } 362 }
558 } 363 }
559 }; 364 };
560 365
561 366
562 /** 367 /**
563 * Calls a {@code cvox.TtsInterface.speak} method in the background page to
564 * speak an utterance. See that method for further details.
565 * @param {string} textString The string of text to be spoken.
566 * @param {cvox.QueueMode} queueMode The queue mode to use.
567 * @param {Object=} properties Speech properties to use for this utterance.
568 */
569 cvox.OptionsPage.speak = function(textString, queueMode, properties) {
570 var speak =
571 /** @type Function} */ (chrome.extension.getBackgroundPage()['speak']);
572 speak.apply(null, arguments);
573 };
574
575 /**
576 * @return {cvox.BrailleTranslatorManager} 368 * @return {cvox.BrailleTranslatorManager}
577 */ 369 */
578 cvox.OptionsPage.getBrailleTranslatorManager = function() { 370 cvox.OptionsPage.getBrailleTranslatorManager = function() {
579 return chrome.extension.getBackgroundPage()['braille_translator_manager']; 371 return chrome.extension.getBackgroundPage()['braille_translator_manager'];
580 }; 372 };
581 373
582 document.addEventListener('DOMContentLoaded', function() { 374 document.addEventListener('DOMContentLoaded', function() {
583 cvox.OptionsPage.init(); 375 cvox.OptionsPage.init();
584 }, false); 376 }, false);
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698