OLD | NEW |
---|---|
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 The entry point for all ChromeVox2 related code for the | 6 * @fileoverview The entry point for all ChromeVox2 related code for the |
7 * background page. | 7 * background page. |
8 */ | 8 */ |
9 | 9 |
10 goog.provide('Background'); | 10 goog.provide('Background'); |
11 goog.provide('global'); | 11 goog.provide('global'); |
12 | 12 |
13 goog.require('AutomationPredicate'); | 13 goog.require('AutomationPredicate'); |
14 goog.require('AutomationUtil'); | 14 goog.require('AutomationUtil'); |
15 goog.require('ChromeVoxState'); | 15 goog.require('ChromeVoxState'); |
16 goog.require('LiveRegions'); | 16 goog.require('LiveRegions'); |
17 goog.require('NextEarcons'); | 17 goog.require('NextEarcons'); |
18 goog.require('Output'); | 18 goog.require('Output'); |
19 goog.require('Output.EventType'); | 19 goog.require('Output.EventType'); |
20 goog.require('PanelCommand'); | |
20 goog.require('constants'); | 21 goog.require('constants'); |
21 goog.require('cursors.Cursor'); | 22 goog.require('cursors.Cursor'); |
22 goog.require('cvox.BrailleKeyCommand'); | 23 goog.require('cvox.BrailleKeyCommand'); |
23 goog.require('cvox.ChromeVoxEditableTextBase'); | 24 goog.require('cvox.ChromeVoxEditableTextBase'); |
24 goog.require('cvox.ChromeVoxKbHandler'); | 25 goog.require('cvox.ChromeVoxKbHandler'); |
25 goog.require('cvox.ClassicEarcons'); | 26 goog.require('cvox.ClassicEarcons'); |
26 goog.require('cvox.ExtensionBridge'); | 27 goog.require('cvox.ExtensionBridge'); |
27 goog.require('cvox.NavBraille'); | 28 goog.require('cvox.NavBraille'); |
28 | 29 |
29 goog.scope(function() { | 30 goog.scope(function() { |
(...skipping 26 matching lines...) Expand all Loading... | |
56 this.classicBlacklistRegExp_ = Background.globsToRegExp_( | 57 this.classicBlacklistRegExp_ = Background.globsToRegExp_( |
57 chrome.runtime.getManifest()['content_scripts'][0]['exclude_globs']); | 58 chrome.runtime.getManifest()['content_scripts'][0]['exclude_globs']); |
58 | 59 |
59 /** | 60 /** |
60 * @type {cursors.Range} | 61 * @type {cursors.Range} |
61 * @private | 62 * @private |
62 */ | 63 */ |
63 this.currentRange_ = null; | 64 this.currentRange_ = null; |
64 | 65 |
65 /** | 66 /** |
67 * @type {cursors.Range} | |
68 * @private | |
69 */ | |
70 this.savedRange_ = null; | |
71 | |
72 /** | |
66 * Which variant of ChromeVox is active. | 73 * Which variant of ChromeVox is active. |
67 * @type {ChromeVoxMode} | 74 * @type {ChromeVoxMode} |
68 * @private | 75 * @private |
69 */ | 76 */ |
70 this.mode_ = ChromeVoxMode.COMPAT; | 77 this.mode_ = ChromeVoxMode.COMPAT; |
71 | 78 |
72 // Manually bind all functions to |this|. | 79 // Manually bind all functions to |this|. |
73 for (var func in this) { | 80 for (var func in this) { |
74 if (typeof(this[func]) == 'function') | 81 if (typeof(this[func]) == 'function') |
75 this[func] = this[func].bind(this); | 82 this[func] = this[func].bind(this); |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
177 }.bind(this)); | 184 }.bind(this)); |
178 | 185 |
179 // If switching out of a ChromeVox Next mode, make sure we cancel | 186 // If switching out of a ChromeVox Next mode, make sure we cancel |
180 // the progress loading sound just in case. | 187 // the progress loading sound just in case. |
181 if ((this.mode_ === ChromeVoxMode.NEXT || | 188 if ((this.mode_ === ChromeVoxMode.NEXT || |
182 this.mode_ === ChromeVoxMode.FORCE_NEXT) && | 189 this.mode_ === ChromeVoxMode.FORCE_NEXT) && |
183 this.mode_ != mode) { | 190 this.mode_ != mode) { |
184 cvox.ChromeVox.earcons.cancelEarcon(cvox.Earcon.PAGE_START_LOADING); | 191 cvox.ChromeVox.earcons.cancelEarcon(cvox.Earcon.PAGE_START_LOADING); |
185 } | 192 } |
186 | 193 |
194 if (mode === ChromeVoxMode.NEXT || | |
195 mode === ChromeVoxMode.FORCE_NEXT) { | |
196 (new PanelCommand(PanelCommandType.ENABLE_MENUS)).send(); | |
197 } else { | |
198 (new PanelCommand(PanelCommandType.DISABLE_MENUS)).send(); | |
199 } | |
200 | |
187 this.mode_ = mode; | 201 this.mode_ = mode; |
188 }, | 202 }, |
189 | 203 |
190 /** | 204 /** |
191 * Mode refreshes takes into account both |url| and the current ChromeVox | 205 * Mode refreshes takes into account both |url| and the current ChromeVox |
192 * range. The latter gets used to decide if the user is or isn't in web | 206 * range. The latter gets used to decide if the user is or isn't in web |
193 * content. The focused state also needs to be set for this info to be | 207 * content. The focused state also needs to be set for this info to be |
194 * reliable. | 208 * reliable. |
195 * @override | 209 * @override |
196 */ | 210 */ |
(...skipping 21 matching lines...) Expand all Loading... | |
218 return this.currentRange_; | 232 return this.currentRange_; |
219 }, | 233 }, |
220 | 234 |
221 /** | 235 /** |
222 * @override | 236 * @override |
223 */ | 237 */ |
224 setCurrentRange: function(newRange) { | 238 setCurrentRange: function(newRange) { |
225 if (!newRange) | 239 if (!newRange) |
226 return; | 240 return; |
227 | 241 |
242 var panelUrl = chrome.extension.getURL('cvox2/background/panel.html'); | |
243 if (newRange.start.node.root.docUrl.indexOf(panelUrl) != 0) { | |
244 this.savedRange_ = new cursors.Range(newRange.start, newRange.end); | |
245 } | |
David Tseng
2016/01/12 20:10:57
nit: remove braces
dmazzoni
2016/01/13 23:26:39
Done.
| |
246 | |
228 this.currentRange_ = newRange; | 247 this.currentRange_ = newRange; |
229 | 248 |
230 if (this.currentRange_) | 249 if (this.currentRange_) |
231 this.currentRange_.start.node.makeVisible(); | 250 this.currentRange_.start.node.makeVisible(); |
232 }, | 251 }, |
233 | 252 |
234 /** Forces ChromeVox Next to be active for all tabs. */ | 253 /** Forces ChromeVox Next to be active for all tabs. */ |
235 forceChromeVoxNextActive: function() { | 254 forceChromeVoxNextActive: function() { |
236 this.setMode(ChromeVoxMode.FORCE_NEXT); | 255 this.setMode(ChromeVoxMode.FORCE_NEXT); |
237 }, | 256 }, |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
278 case 'nextButton': | 297 case 'nextButton': |
279 dir = Dir.FORWARD; | 298 dir = Dir.FORWARD; |
280 pred = AutomationPredicate.button; | 299 pred = AutomationPredicate.button; |
281 predErrorMsg = 'no_next_button'; | 300 predErrorMsg = 'no_next_button'; |
282 break; | 301 break; |
283 case 'previousButton': | 302 case 'previousButton': |
284 dir = Dir.BACKWARD; | 303 dir = Dir.BACKWARD; |
285 pred = AutomationPredicate.button; | 304 pred = AutomationPredicate.button; |
286 predErrorMsg = 'no_previous_button'; | 305 predErrorMsg = 'no_previous_button'; |
287 break; | 306 break; |
288 case 'nextCheckBox': | 307 case 'nextCheckbox': |
289 dir = Dir.FORWARD; | 308 dir = Dir.FORWARD; |
290 pred = AutomationPredicate.checkBox; | 309 pred = AutomationPredicate.checkBox; |
291 predErrorMsg = 'no_next_checkbox'; | 310 predErrorMsg = 'no_next_checkbox'; |
292 break; | 311 break; |
293 case 'previousCheckBox': | 312 case 'previousCheckbox': |
294 dir = Dir.BACKWARD; | 313 dir = Dir.BACKWARD; |
295 pred = AutomationPredicate.checkBox; | 314 pred = AutomationPredicate.checkBox; |
296 predErrorMsg = 'no_previous_checkbox'; | 315 predErrorMsg = 'no_previous_checkbox'; |
297 break; | 316 break; |
298 case 'nextComboBox': | 317 case 'nextComboBox': |
299 dir = Dir.FORWARD; | 318 dir = Dir.FORWARD; |
300 pred = AutomationPredicate.comboBox; | 319 pred = AutomationPredicate.comboBox; |
301 predErrorMsg = 'no_next_combo_box'; | 320 predErrorMsg = 'no_next_combo_box'; |
302 break; | 321 break; |
303 case 'previousComboBox': | 322 case 'previousComboBox': |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
359 dir = Dir.FORWARD; | 378 dir = Dir.FORWARD; |
360 pred = AutomationPredicate.visitedLink; | 379 pred = AutomationPredicate.visitedLink; |
361 predErrorMsg = 'no_next_visited_link'; | 380 predErrorMsg = 'no_next_visited_link'; |
362 break; | 381 break; |
363 case 'previousVisitedLink': | 382 case 'previousVisitedLink': |
364 dir = Dir.BACKWARD; | 383 dir = Dir.BACKWARD; |
365 pred = AutomationPredicate.visitedLink; | 384 pred = AutomationPredicate.visitedLink; |
366 predErrorMsg = 'no_previous_visited_link'; | 385 predErrorMsg = 'no_previous_visited_link'; |
367 break; | 386 break; |
368 case 'right': | 387 case 'right': |
369 case 'nextElement': | 388 case 'nextObject': |
370 current = current.move(cursors.Unit.DOM_NODE, Dir.FORWARD); | 389 current = current.move(cursors.Unit.DOM_NODE, Dir.FORWARD); |
371 break; | 390 break; |
372 case 'left': | 391 case 'left': |
373 case 'previousElement': | 392 case 'previousObject': |
374 current = current.move(cursors.Unit.DOM_NODE, Dir.BACKWARD); | 393 current = current.move(cursors.Unit.DOM_NODE, Dir.BACKWARD); |
375 break; | 394 break; |
376 case 'goToBeginning': | 395 case 'jumpToTop': |
David Tseng
2016/01/12 19:24:42
goToEnd/jumpToBottom as well?
dmazzoni
2016/01/13 23:26:39
Done.
| |
377 var node = | 396 var node = |
378 AutomationUtil.findNodePost(current.start.node.root, | 397 AutomationUtil.findNodePost(current.start.node.root, |
379 Dir.FORWARD, | 398 Dir.FORWARD, |
380 AutomationPredicate.leaf); | 399 AutomationPredicate.leaf); |
381 if (node) | 400 if (node) |
382 current = cursors.Range.fromNode(node); | 401 current = cursors.Range.fromNode(node); |
383 break; | 402 break; |
384 case 'goToEnd': | 403 case 'goToEnd': |
385 var node = | 404 var node = |
386 AutomationUtil.findNodePost(current.start.node.root, | 405 AutomationUtil.findNodePost(current.start.node.root, |
387 Dir.BACKWARD, | 406 Dir.BACKWARD, |
388 AutomationPredicate.leaf); | 407 AutomationPredicate.leaf); |
389 if (node) | 408 if (node) |
390 current = cursors.Range.fromNode(node); | 409 current = cursors.Range.fromNode(node); |
391 break; | 410 break; |
392 case 'forceClickOnCurrentItem': | 411 case 'forceClickOnCurrentItem': |
393 case 'doDefault': | 412 case 'performDefaultAction': |
394 if (this.currentRange_) { | 413 if (this.currentRange_) { |
395 var actionNode = this.currentRange_.start.node; | 414 var actionNode = this.currentRange_.start.node; |
396 if (actionNode.role == RoleType.inlineTextBox) | 415 if (actionNode.role == RoleType.inlineTextBox) |
397 actionNode = actionNode.parent; | 416 actionNode = actionNode.parent; |
398 actionNode.doDefault(); | 417 actionNode.doDefault(); |
399 } | 418 } |
400 // Skip all other processing; if focus changes, we should get an event | 419 // Skip all other processing; if focus changes, we should get an event |
401 // for that. | 420 // for that. |
402 return false; | 421 return false; |
403 case 'continuousRead': | 422 case 'readFromHere': |
404 global.isReadingContinuously = true; | 423 global.isReadingContinuously = true; |
405 var continueReading = function(prevRange) { | 424 var continueReading = function(prevRange) { |
406 if (!global.isReadingContinuously || !this.currentRange_) | 425 if (!global.isReadingContinuously || !this.currentRange_) |
407 return; | 426 return; |
408 | 427 |
409 new Output().withSpeechAndBraille( | 428 new Output().withSpeechAndBraille( |
410 this.currentRange_, prevRange, Output.EventType.NAVIGATE) | 429 this.currentRange_, prevRange, Output.EventType.NAVIGATE) |
411 .onSpeechEnd(function() { continueReading(prevRange); }) | 430 .onSpeechEnd(function() { continueReading(prevRange); }) |
412 .go(); | 431 .go(); |
413 prevRange = this.currentRange_; | 432 prevRange = this.currentRange_; |
414 this.setCurrentRange( | 433 this.setCurrentRange( |
415 this.currentRange_.move(cursors.Unit.NODE, Dir.FORWARD)); | 434 this.currentRange_.move(cursors.Unit.NODE, Dir.FORWARD)); |
416 | 435 |
417 if (!this.currentRange_ || this.currentRange_.equals(prevRange)) | 436 if (!this.currentRange_ || this.currentRange_.equals(prevRange)) |
418 global.isReadingContinuously = false; | 437 global.isReadingContinuously = false; |
419 }.bind(this); | 438 }.bind(this); |
420 | 439 |
421 continueReading(null); | 440 continueReading(null); |
422 return false; | 441 return false; |
423 case 'showContextMenu': | 442 case 'contextMenu': |
424 if (this.currentRange_) { | 443 if (this.currentRange_) { |
425 var actionNode = this.currentRange_.start.node; | 444 var actionNode = this.currentRange_.start.node; |
426 if (actionNode.role == RoleType.inlineTextBox) | 445 if (actionNode.role == RoleType.inlineTextBox) |
427 actionNode = actionNode.parent; | 446 actionNode = actionNode.parent; |
428 actionNode.showContextMenu(); | 447 actionNode.showContextMenu(); |
429 return false; | 448 return false; |
430 } | 449 } |
431 break; | 450 break; |
432 case 'showOptionsPage': | 451 case 'showOptionsPage': |
433 chrome.runtime.openOptionsPage(); | 452 chrome.runtime.openOptionsPage(); |
(...skipping 23 matching lines...) Expand all Loading... | |
457 newMode == ChromeVoxMode.CLASSIC || newMode == ChromeVoxMode.COMPAT; | 476 newMode == ChromeVoxMode.CLASSIC || newMode == ChromeVoxMode.COMPAT; |
458 | 477 |
459 // Leaving unlocalized as 'next' isn't an official name. | 478 // Leaving unlocalized as 'next' isn't an official name. |
460 cvox.ChromeVox.tts.speak(isClassic ? | 479 cvox.ChromeVox.tts.speak(isClassic ? |
461 'classic' : 'next', cvox.QueueMode.FLUSH, {doNotInterrupt: true}); | 480 'classic' : 'next', cvox.QueueMode.FLUSH, {doNotInterrupt: true}); |
462 break; | 481 break; |
463 case 'toggleStickyMode': | 482 case 'toggleStickyMode': |
464 cvox.ChromeVoxBackground.setPref('sticky', | 483 cvox.ChromeVoxBackground.setPref('sticky', |
465 !cvox.ChromeVox.isStickyPrefOn, | 484 !cvox.ChromeVox.isStickyPrefOn, |
466 true); | 485 true); |
486 case 'openChromeVoxMenus': | |
487 (new PanelCommand(PanelCommandType.OPEN_MENUS)).send(); | |
488 break; | |
489 case 'decreaseTtsRate': | |
490 this.increaseOrDecreaseSpeechProperty_(cvox.AbstractTts.RATE, false); | |
491 break; | |
492 case 'increaseTtsRate': | |
493 this.increaseOrDecreaseSpeechProperty_(cvox.AbstractTts.RATE, true); | |
494 break; | |
495 case 'decreaseTtsPitch': | |
496 this.increaseOrDecreaseSpeechProperty_(cvox.AbstractTts.PITCH, false); | |
497 break; | |
498 case 'increaseTtsPitch': | |
499 this.increaseOrDecreaseSpeechProperty_(cvox.AbstractTts.PITCH, true); | |
500 break; | |
501 case 'decreaseTtsVolume': | |
502 this.increaseOrDecreaseSpeechProperty_(cvox.AbstractTts.VOLUME, false); | |
503 break; | |
504 case 'increaseTtsVolume': | |
505 this.increaseOrDecreaseSpeechProperty_(cvox.AbstractTts.VOLUME, true); | |
467 break; | 506 break; |
468 default: | 507 default: |
469 return true; | 508 return true; |
470 } | 509 } |
471 | 510 |
472 if (pred) { | 511 if (pred) { |
473 var node = AutomationUtil.findNextNode( | 512 var node = AutomationUtil.findNextNode( |
474 current.getBound(dir).node, dir, pred); | 513 current.getBound(dir).node, dir, pred); |
475 | 514 |
476 if (node) { | 515 if (node) { |
477 current = cursors.Range.fromNode(node); | 516 current = cursors.Range.fromNode(node); |
478 } else { | 517 } else { |
479 if (predErrorMsg) { | 518 if (predErrorMsg) { |
480 cvox.ChromeVox.tts.speak(Msgs.getMsg(predErrorMsg), | 519 cvox.ChromeVox.tts.speak(Msgs.getMsg(predErrorMsg), |
481 cvox.QueueMode.FLUSH); | 520 cvox.QueueMode.FLUSH); |
482 } | 521 } |
483 return false; | 522 return false; |
484 } | 523 } |
485 } | 524 } |
486 | 525 |
487 if (current) { | 526 if (current) |
488 // TODO(dtseng): Figure out what it means to focus a range. | 527 this.navigateToRange_(current); |
489 var actionNode = current.start.node; | |
490 if (actionNode.role == RoleType.inlineTextBox) | |
491 actionNode = actionNode.parent; | |
492 actionNode.focus(); | |
493 | |
494 var prevRange = this.currentRange_; | |
495 this.setCurrentRange(current); | |
496 | |
497 new Output().withSpeechAndBraille( | |
498 this.currentRange_, prevRange, Output.EventType.NAVIGATE) | |
499 .withQueueMode(cvox.QueueMode.FLUSH) | |
500 .go(); | |
501 } | |
502 | 528 |
503 return false; | 529 return false; |
504 }, | 530 }, |
505 | 531 |
506 /** | 532 /** |
533 * Increase or decrease a speech property and make an announcement. | |
534 * @param {string} propertyName The name of the property to change. | |
535 * @param {boolean} increase If true, increases the property value by one | |
536 * step size, otherwise decreases. | |
537 */ | |
538 increaseOrDecreaseSpeechProperty_: function(propertyName, increase) { | |
539 cvox.ChromeVox.tts.increaseOrDecreaseProperty(propertyName, increase); | |
540 var announcement; | |
541 var valueAsPercent = Math.round( | |
542 cvox.ChromeVox.tts.propertyToPercentage(propertyName) * 100); | |
543 switch (propertyName) { | |
544 case cvox.AbstractTts.RATE: | |
545 announcement = Msgs.getMsg('announce_rate', [valueAsPercent]); | |
546 break; | |
547 case cvox.AbstractTts.PITCH: | |
548 announcement = Msgs.getMsg('announce_pitch', [valueAsPercent]); | |
549 break; | |
550 case cvox.AbstractTts.VOLUME: | |
551 announcement = Msgs.getMsg('announce_volume', [valueAsPercent]); | |
552 break; | |
553 } | |
554 if (announcement) { | |
555 cvox.ChromeVox.tts.speak( | |
556 announcement, cvox.QueueMode.FLUSH, | |
557 cvox.AbstractTts.PERSONALITY_ANNOTATION); | |
558 } | |
559 }, | |
560 | |
561 /** | |
562 * Navigate to the given range - it both sets the range and outputs it. | |
563 * @param {!cursors.Range} range The new range. | |
564 * @private | |
565 */ | |
566 navigateToRange_: function(range) { | |
567 // TODO(dtseng): Figure out what it means to focus a range. | |
568 var actionNode = range.start.node; | |
569 if (actionNode.role == RoleType.inlineTextBox) | |
570 actionNode = actionNode.parent; | |
571 actionNode.focus(); | |
572 | |
573 var prevRange = this.currentRange_; | |
574 this.setCurrentRange(range); | |
575 | |
576 new Output().withSpeechAndBraille( | |
577 range, prevRange, Output.EventType.NAVIGATE).go(); | |
578 }, | |
579 | |
580 /** | |
507 * Handles key down events. | 581 * Handles key down events. |
508 * @param {Event} evt The key down event to process. | 582 * @param {Event} evt The key down event to process. |
509 * @return {boolean} True if the default action should be performed. | 583 * @return {boolean} True if the default action should be performed. |
510 */ | 584 */ |
511 onKeyDown: function(evt) { | 585 onKeyDown: function(evt) { |
512 evt.stickyMode = cvox.ChromeVox.isStickyModeOn() && cvox.ChromeVox.isActive; | 586 evt.stickyMode = cvox.ChromeVox.isStickyModeOn() && cvox.ChromeVox.isActive; |
513 if (this.mode_ != ChromeVoxMode.CLASSIC && | 587 if (this.mode_ != ChromeVoxMode.CLASSIC && |
514 !cvox.ChromeVoxKbHandler.basicKeyDownActionsListener(evt)) { | 588 !cvox.ChromeVoxKbHandler.basicKeyDownActionsListener(evt)) { |
515 evt.preventDefault(); | 589 evt.preventDefault(); |
516 evt.stopPropagation(); | 590 evt.stopPropagation(); |
(...skipping 15 matching lines...) Expand all Loading... | |
532 * @param {!cvox.BrailleKeyEvent} evt | 606 * @param {!cvox.BrailleKeyEvent} evt |
533 * @param {!cvox.NavBraille} content | 607 * @param {!cvox.NavBraille} content |
534 * @return {boolean} True if evt was processed. | 608 * @return {boolean} True if evt was processed. |
535 */ | 609 */ |
536 onBrailleKeyEvent: function(evt, content) { | 610 onBrailleKeyEvent: function(evt, content) { |
537 if (this.mode_ === ChromeVoxMode.CLASSIC) | 611 if (this.mode_ === ChromeVoxMode.CLASSIC) |
538 return false; | 612 return false; |
539 | 613 |
540 switch (evt.command) { | 614 switch (evt.command) { |
541 case cvox.BrailleKeyCommand.PAN_LEFT: | 615 case cvox.BrailleKeyCommand.PAN_LEFT: |
542 this.onGotCommand('previousElement'); | 616 this.onGotCommand('previousObject'); |
543 break; | 617 break; |
544 case cvox.BrailleKeyCommand.PAN_RIGHT: | 618 case cvox.BrailleKeyCommand.PAN_RIGHT: |
545 this.onGotCommand('nextElement'); | 619 this.onGotCommand('nextObject'); |
546 break; | 620 break; |
547 case cvox.BrailleKeyCommand.LINE_UP: | 621 case cvox.BrailleKeyCommand.LINE_UP: |
548 this.onGotCommand('previousLine'); | 622 this.onGotCommand('previousLine'); |
549 break; | 623 break; |
550 case cvox.BrailleKeyCommand.LINE_DOWN: | 624 case cvox.BrailleKeyCommand.LINE_DOWN: |
551 this.onGotCommand('nextLine'); | 625 this.onGotCommand('nextLine'); |
552 break; | 626 break; |
553 case cvox.BrailleKeyCommand.TOP: | 627 case cvox.BrailleKeyCommand.TOP: |
554 this.onGotCommand('goToBeginning'); | 628 this.onGotCommand('jumpToTop'); |
555 break; | 629 break; |
556 case cvox.BrailleKeyCommand.BOTTOM: | 630 case cvox.BrailleKeyCommand.BOTTOM: |
557 this.onGotCommand('goToEnd'); | 631 this.onGotCommand('jumpToBottom'); |
558 break; | 632 break; |
559 case cvox.BrailleKeyCommand.ROUTING: | 633 case cvox.BrailleKeyCommand.ROUTING: |
560 this.brailleRoutingCommand_( | 634 this.brailleRoutingCommand_( |
561 content.text, | 635 content.text, |
562 // Cast ok since displayPosition is always defined in this case. | 636 // Cast ok since displayPosition is always defined in this case. |
563 /** @type {number} */ (evt.displayPosition)); | 637 /** @type {number} */ (evt.displayPosition)); |
564 break; | 638 break; |
565 default: | 639 default: |
566 return false; | 640 return false; |
567 } | 641 } |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
653 if (action == 'getIsClassicEnabled') { | 727 if (action == 'getIsClassicEnabled') { |
654 var url = msg['url']; | 728 var url = msg['url']; |
655 var isClassicEnabled = this.shouldEnableClassicForUrl_(url); | 729 var isClassicEnabled = this.shouldEnableClassicForUrl_(url); |
656 port.postMessage({ | 730 port.postMessage({ |
657 target: 'next', | 731 target: 'next', |
658 isClassicEnabled: isClassicEnabled | 732 isClassicEnabled: isClassicEnabled |
659 }); | 733 }); |
660 } | 734 } |
661 break; | 735 break; |
662 } | 736 } |
663 } | 737 }, |
738 | |
739 /** | |
740 * Restore the range to the last range that was *not* in the ChromeVox | |
741 * panel. This is used when the ChromeVox Panel closes. | |
742 */ | |
743 restoreCurrentRange: function() { | |
744 if (this.savedRange_) { | |
745 var containingWebView = this.savedRange_.start.node; | |
746 while (containingWebView && containingWebView.role != RoleType.webView) { | |
747 containingWebView = containingWebView.parent; | |
748 } | |
David Tseng
2016/01/12 20:10:57
nit: remove braces
dmazzoni
2016/01/13 23:26:39
Done.
| |
749 if (containingWebView) | |
750 containingWebView.focus(); | |
David Tseng
2016/01/12 20:10:57
Does this restore focus properly? What if savedRan
dmazzoni
2016/01/13 23:26:39
It's okay to call focus() on a dead node, it's a n
| |
751 | |
752 this.navigateToRange_(this.savedRange_); | |
753 this.savedRange_ = null; | |
754 } | |
755 }, | |
664 }; | 756 }; |
665 | 757 |
666 /** | 758 /** |
667 * Converts a list of globs, as used in the extension manifest, to a regular | 759 * Converts a list of globs, as used in the extension manifest, to a regular |
668 * expression that matches if and only if any of the globs in the list matches. | 760 * expression that matches if and only if any of the globs in the list matches. |
669 * @param {!Array<string>} globs | 761 * @param {!Array<string>} globs |
670 * @return {!RegExp} | 762 * @return {!RegExp} |
671 * @private | 763 * @private |
672 */ | 764 */ |
673 Background.globsToRegExp_ = function(globs) { | 765 Background.globsToRegExp_ = function(globs) { |
674 return new RegExp('^(' + globs.map(function(glob) { | 766 return new RegExp('^(' + globs.map(function(glob) { |
675 return glob.replace(/[.+^$(){}|[\]\\]/g, '\\$&') | 767 return glob.replace(/[.+^$(){}|[\]\\]/g, '\\$&') |
676 .replace(/\*/g, '.*') | 768 .replace(/\*/g, '.*') |
677 .replace(/\?/g, '.'); | 769 .replace(/\?/g, '.'); |
678 }).join('|') + ')$'); | 770 }).join('|') + ')$'); |
679 }; | 771 }; |
680 | 772 |
681 /** @type {Background} */ | 773 /** @type {Background} */ |
682 global.backgroundObj = new Background(); | 774 global.backgroundObj = new Background(); |
683 | 775 |
684 }); // goog.scope | 776 }); // goog.scope |
OLD | NEW |