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

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

Issue 1684693002: Revert of Implement ChromeVox Next menus. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@panel_view_type
Patch Set: generating revert using git Created 4 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
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 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');
21 goog.require('constants'); 20 goog.require('constants');
22 goog.require('cursors.Cursor'); 21 goog.require('cursors.Cursor');
23 goog.require('cvox.BrailleKeyCommand'); 22 goog.require('cvox.BrailleKeyCommand');
24 goog.require('cvox.ChromeVoxEditableTextBase'); 23 goog.require('cvox.ChromeVoxEditableTextBase');
25 goog.require('cvox.ChromeVoxKbHandler'); 24 goog.require('cvox.ChromeVoxKbHandler');
26 goog.require('cvox.ClassicEarcons'); 25 goog.require('cvox.ClassicEarcons');
27 goog.require('cvox.ExtensionBridge'); 26 goog.require('cvox.ExtensionBridge');
28 goog.require('cvox.NavBraille'); 27 goog.require('cvox.NavBraille');
29 28
30 goog.scope(function() { 29 goog.scope(function() {
(...skipping 26 matching lines...) Expand all
57 this.classicBlacklistRegExp_ = Background.globsToRegExp_( 56 this.classicBlacklistRegExp_ = Background.globsToRegExp_(
58 chrome.runtime.getManifest()['content_scripts'][0]['exclude_globs']); 57 chrome.runtime.getManifest()['content_scripts'][0]['exclude_globs']);
59 58
60 /** 59 /**
61 * @type {cursors.Range} 60 * @type {cursors.Range}
62 * @private 61 * @private
63 */ 62 */
64 this.currentRange_ = null; 63 this.currentRange_ = null;
65 64
66 /** 65 /**
67 * @type {cursors.Range}
68 * @private
69 */
70 this.savedRange_ = null;
71
72 /**
73 * Which variant of ChromeVox is active. 66 * Which variant of ChromeVox is active.
74 * @type {ChromeVoxMode} 67 * @type {ChromeVoxMode}
75 * @private 68 * @private
76 */ 69 */
77 this.mode_ = ChromeVoxMode.COMPAT; 70 this.mode_ = ChromeVoxMode.COMPAT;
78 71
79 // Manually bind all functions to |this|. 72 // Manually bind all functions to |this|.
80 for (var func in this) { 73 for (var func in this) {
81 if (typeof(this[func]) == 'function') 74 if (typeof(this[func]) == 'function')
82 this[func] = this[func].bind(this); 75 this[func] = this[func].bind(this);
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
194 }.bind(this)); 187 }.bind(this));
195 188
196 // If switching out of a ChromeVox Next mode, make sure we cancel 189 // If switching out of a ChromeVox Next mode, make sure we cancel
197 // the progress loading sound just in case. 190 // the progress loading sound just in case.
198 if ((this.mode_ === ChromeVoxMode.NEXT || 191 if ((this.mode_ === ChromeVoxMode.NEXT ||
199 this.mode_ === ChromeVoxMode.FORCE_NEXT) && 192 this.mode_ === ChromeVoxMode.FORCE_NEXT) &&
200 this.mode_ != mode) { 193 this.mode_ != mode) {
201 cvox.ChromeVox.earcons.cancelEarcon(cvox.Earcon.PAGE_START_LOADING); 194 cvox.ChromeVox.earcons.cancelEarcon(cvox.Earcon.PAGE_START_LOADING);
202 } 195 }
203 196
204 if (mode === ChromeVoxMode.NEXT ||
205 mode === ChromeVoxMode.FORCE_NEXT) {
206 (new PanelCommand(PanelCommandType.ENABLE_MENUS)).send();
207 } else {
208 (new PanelCommand(PanelCommandType.DISABLE_MENUS)).send();
209 }
210
211 this.mode_ = mode; 197 this.mode_ = mode;
212 }, 198 },
213 199
214 /** 200 /**
215 * Mode refreshes takes into account both |url| and the current ChromeVox 201 * Mode refreshes takes into account both |url| and the current ChromeVox
216 * range. The latter gets used to decide if the user is or isn't in web 202 * range. The latter gets used to decide if the user is or isn't in web
217 * content. The focused state also needs to be set for this info to be 203 * content. The focused state also needs to be set for this info to be
218 * reliable. 204 * reliable.
219 * @override 205 * @override
220 */ 206 */
(...skipping 21 matching lines...) Expand all
242 return this.currentRange_; 228 return this.currentRange_;
243 }, 229 },
244 230
245 /** 231 /**
246 * @override 232 * @override
247 */ 233 */
248 setCurrentRange: function(newRange) { 234 setCurrentRange: function(newRange) {
249 if (!newRange) 235 if (!newRange)
250 return; 236 return;
251 237
252 var panelUrl = chrome.extension.getURL('cvox2/background/panel.html');
253 if (newRange.start.node.root.docUrl.indexOf(panelUrl) != 0)
254 this.savedRange_ = new cursors.Range(newRange.start, newRange.end);
255
256 this.currentRange_ = newRange; 238 this.currentRange_ = newRange;
257 239
258 if (this.currentRange_) 240 if (this.currentRange_)
259 this.currentRange_.start.node.makeVisible(); 241 this.currentRange_.start.node.makeVisible();
260 }, 242 },
261 243
262 /** Forces ChromeVox Next to be active for all tabs. */ 244 /** Forces ChromeVox Next to be active for all tabs. */
263 forceChromeVoxNextActive: function() { 245 forceChromeVoxNextActive: function() {
264 this.setMode(ChromeVoxMode.FORCE_NEXT); 246 this.setMode(ChromeVoxMode.FORCE_NEXT);
265 }, 247 },
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
306 case 'nextButton': 288 case 'nextButton':
307 dir = Dir.FORWARD; 289 dir = Dir.FORWARD;
308 pred = AutomationPredicate.button; 290 pred = AutomationPredicate.button;
309 predErrorMsg = 'no_next_button'; 291 predErrorMsg = 'no_next_button';
310 break; 292 break;
311 case 'previousButton': 293 case 'previousButton':
312 dir = Dir.BACKWARD; 294 dir = Dir.BACKWARD;
313 pred = AutomationPredicate.button; 295 pred = AutomationPredicate.button;
314 predErrorMsg = 'no_previous_button'; 296 predErrorMsg = 'no_previous_button';
315 break; 297 break;
316 case 'nextCheckbox': 298 case 'nextCheckBox':
317 dir = Dir.FORWARD; 299 dir = Dir.FORWARD;
318 pred = AutomationPredicate.checkBox; 300 pred = AutomationPredicate.checkBox;
319 predErrorMsg = 'no_next_checkbox'; 301 predErrorMsg = 'no_next_checkbox';
320 break; 302 break;
321 case 'previousCheckbox': 303 case 'previousCheckBox':
322 dir = Dir.BACKWARD; 304 dir = Dir.BACKWARD;
323 pred = AutomationPredicate.checkBox; 305 pred = AutomationPredicate.checkBox;
324 predErrorMsg = 'no_previous_checkbox'; 306 predErrorMsg = 'no_previous_checkbox';
325 break; 307 break;
326 case 'nextComboBox': 308 case 'nextComboBox':
327 dir = Dir.FORWARD; 309 dir = Dir.FORWARD;
328 pred = AutomationPredicate.comboBox; 310 pred = AutomationPredicate.comboBox;
329 predErrorMsg = 'no_next_combo_box'; 311 predErrorMsg = 'no_next_combo_box';
330 break; 312 break;
331 case 'previousComboBox': 313 case 'previousComboBox':
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
387 dir = Dir.FORWARD; 369 dir = Dir.FORWARD;
388 pred = AutomationPredicate.visitedLink; 370 pred = AutomationPredicate.visitedLink;
389 predErrorMsg = 'no_next_visited_link'; 371 predErrorMsg = 'no_next_visited_link';
390 break; 372 break;
391 case 'previousVisitedLink': 373 case 'previousVisitedLink':
392 dir = Dir.BACKWARD; 374 dir = Dir.BACKWARD;
393 pred = AutomationPredicate.visitedLink; 375 pred = AutomationPredicate.visitedLink;
394 predErrorMsg = 'no_previous_visited_link'; 376 predErrorMsg = 'no_previous_visited_link';
395 break; 377 break;
396 case 'right': 378 case 'right':
397 case 'nextObject': 379 case 'nextElement':
398 current = current.move(cursors.Unit.DOM_NODE, Dir.FORWARD); 380 current = current.move(cursors.Unit.DOM_NODE, Dir.FORWARD);
399 break; 381 break;
400 case 'left': 382 case 'left':
401 case 'previousObject': 383 case 'previousElement':
402 current = current.move(cursors.Unit.DOM_NODE, Dir.BACKWARD); 384 current = current.move(cursors.Unit.DOM_NODE, Dir.BACKWARD);
403 break; 385 break;
404 case 'jumpToTop': 386 case 'goToBeginning':
405 var node = 387 var node =
406 AutomationUtil.findNodePost(current.start.node.root, 388 AutomationUtil.findNodePost(current.start.node.root,
407 Dir.FORWARD, 389 Dir.FORWARD,
408 AutomationPredicate.leaf); 390 AutomationPredicate.leaf);
409 if (node) 391 if (node)
410 current = cursors.Range.fromNode(node); 392 current = cursors.Range.fromNode(node);
411 break; 393 break;
412 case 'jumpToBottom': 394 case 'goToEnd':
413 var node = 395 var node =
414 AutomationUtil.findNodePost(current.start.node.root, 396 AutomationUtil.findNodePost(current.start.node.root,
415 Dir.BACKWARD, 397 Dir.BACKWARD,
416 AutomationPredicate.leaf); 398 AutomationPredicate.leaf);
417 if (node) 399 if (node)
418 current = cursors.Range.fromNode(node); 400 current = cursors.Range.fromNode(node);
419 break; 401 break;
420 case 'forceClickOnCurrentItem': 402 case 'forceClickOnCurrentItem':
421 case 'performDefaultAction': 403 case 'doDefault':
422 if (this.currentRange_) { 404 if (this.currentRange_) {
423 var actionNode = this.currentRange_.start.node; 405 var actionNode = this.currentRange_.start.node;
424 if (actionNode.role == RoleType.inlineTextBox) 406 if (actionNode.role == RoleType.inlineTextBox)
425 actionNode = actionNode.parent; 407 actionNode = actionNode.parent;
426 actionNode.doDefault(); 408 actionNode.doDefault();
427 } 409 }
428 // Skip all other processing; if focus changes, we should get an event 410 // Skip all other processing; if focus changes, we should get an event
429 // for that. 411 // for that.
430 return false; 412 return false;
431 case 'readFromHere': 413 case 'continuousRead':
432 global.isReadingContinuously = true; 414 global.isReadingContinuously = true;
433 var continueReading = function() { 415 var continueReading = function() {
434 if (!global.isReadingContinuously || !this.currentRange_) 416 if (!global.isReadingContinuously || !this.currentRange_)
435 return; 417 return;
436 418
437 var prevRange = this.currentRange_; 419 var prevRange = this.currentRange_;
438 var newRange = 420 var newRange =
439 this.currentRange_.move(cursors.Unit.DOM_NODE, Dir.FORWARD); 421 this.currentRange_.move(cursors.Unit.DOM_NODE, Dir.FORWARD);
440 422
441 // Stop if we've wrapped back to the document. 423 // Stop if we've wrapped back to the document.
(...skipping 11 matching lines...) Expand all
453 .onSpeechEnd(continueReading) 435 .onSpeechEnd(continueReading)
454 .go(); 436 .go();
455 }.bind(this); 437 }.bind(this);
456 438
457 new Output().withSpeechAndBraille( 439 new Output().withSpeechAndBraille(
458 this.currentRange_, null, Output.EventType.NAVIGATE) 440 this.currentRange_, null, Output.EventType.NAVIGATE)
459 .onSpeechEnd(continueReading) 441 .onSpeechEnd(continueReading)
460 .go(); 442 .go();
461 443
462 return false; 444 return false;
463 case 'contextMenu': 445 case 'showContextMenu':
464 if (this.currentRange_) { 446 if (this.currentRange_) {
465 var actionNode = this.currentRange_.start.node; 447 var actionNode = this.currentRange_.start.node;
466 if (actionNode.role == RoleType.inlineTextBox) 448 if (actionNode.role == RoleType.inlineTextBox)
467 actionNode = actionNode.parent; 449 actionNode = actionNode.parent;
468 actionNode.showContextMenu(); 450 actionNode.showContextMenu();
469 return false; 451 return false;
470 } 452 }
471 break; 453 break;
472 case 'showOptionsPage': 454 case 'showOptionsPage':
473 chrome.runtime.openOptionsPage(); 455 chrome.runtime.openOptionsPage();
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
508 if (cvox.ChromeVox.isStickyPrefOn) 490 if (cvox.ChromeVox.isStickyPrefOn)
509 chrome.accessibilityPrivate.setKeyboardListener(true, true); 491 chrome.accessibilityPrivate.setKeyboardListener(true, true);
510 else 492 else
511 chrome.accessibilityPrivate.setKeyboardListener(true, false); 493 chrome.accessibilityPrivate.setKeyboardListener(true, false);
512 return false; 494 return false;
513 case 'passThroughMode': 495 case 'passThroughMode':
514 cvox.ChromeVox.passThroughMode = true; 496 cvox.ChromeVox.passThroughMode = true;
515 cvox.ChromeVox.tts.speak( 497 cvox.ChromeVox.tts.speak(
516 Msgs.getMsg('pass_through_key'), cvox.QueueMode.QUEUE); 498 Msgs.getMsg('pass_through_key'), cvox.QueueMode.QUEUE);
517 return true; 499 return true;
518 case 'openChromeVoxMenus':
519 (new PanelCommand(PanelCommandType.OPEN_MENUS)).send();
520 break;
521 case 'decreaseTtsRate':
522 this.increaseOrDecreaseSpeechProperty_(cvox.AbstractTts.RATE, false);
523 break;
524 case 'increaseTtsRate':
525 this.increaseOrDecreaseSpeechProperty_(cvox.AbstractTts.RATE, true);
526 break;
527 case 'decreaseTtsPitch':
528 this.increaseOrDecreaseSpeechProperty_(cvox.AbstractTts.PITCH, false);
529 break;
530 case 'increaseTtsPitch':
531 this.increaseOrDecreaseSpeechProperty_(cvox.AbstractTts.PITCH, true);
532 break;
533 case 'decreaseTtsVolume':
534 this.increaseOrDecreaseSpeechProperty_(cvox.AbstractTts.VOLUME, false);
535 break;
536 case 'increaseTtsVolume':
537 this.increaseOrDecreaseSpeechProperty_(cvox.AbstractTts.VOLUME, true);
538 break;
539 default: 500 default:
540 return true; 501 return true;
541 } 502 }
542 503
543 if (pred) { 504 if (pred) {
544 var node = AutomationUtil.findNextNode( 505 var node = AutomationUtil.findNextNode(
545 current.getBound(dir).node, dir, pred); 506 current.getBound(dir).node, dir, pred);
546 507
547 if (node) { 508 if (node) {
548 current = cursors.Range.fromNode(node); 509 current = cursors.Range.fromNode(node);
549 } else { 510 } else {
550 if (predErrorMsg) { 511 if (predErrorMsg) {
551 cvox.ChromeVox.tts.speak(Msgs.getMsg(predErrorMsg), 512 cvox.ChromeVox.tts.speak(Msgs.getMsg(predErrorMsg),
552 cvox.QueueMode.FLUSH); 513 cvox.QueueMode.FLUSH);
553 } 514 }
554 return false; 515 return false;
555 } 516 }
556 } 517 }
557 518
558 if (current) 519 if (current) {
559 this.navigateToRange_(current); 520 // TODO(dtseng): Figure out what it means to focus a range.
521 var actionNode = current.start.node;
522 if (actionNode.role == RoleType.inlineTextBox)
523 actionNode = actionNode.parent;
524
525 // Iframes, when focused, causes the child webArea to fire focus event.
526 // This can result in getting stuck when navigating backward.
527 if (actionNode.role != RoleType.iframe && !actionNode.state.focused)
528 actionNode.focus();
529
530 var prevRange = this.currentRange_;
531 this.setCurrentRange(current);
532
533 new Output().withSpeechAndBraille(
534 this.currentRange_, prevRange, Output.EventType.NAVIGATE)
535 .withQueueMode(cvox.QueueMode.FLUSH)
536 .go();
537 }
560 538
561 return false; 539 return false;
562 }, 540 },
563 541
564 /** 542 /**
565 * Increase or decrease a speech property and make an announcement.
566 * @param {string} propertyName The name of the property to change.
567 * @param {boolean} increase If true, increases the property value by one
568 * step size, otherwise decreases.
569 */
570 increaseOrDecreaseSpeechProperty_: function(propertyName, increase) {
571 cvox.ChromeVox.tts.increaseOrDecreaseProperty(propertyName, increase);
572 var announcement;
573 var valueAsPercent = Math.round(
574 cvox.ChromeVox.tts.propertyToPercentage(propertyName) * 100);
575 switch (propertyName) {
576 case cvox.AbstractTts.RATE:
577 announcement = Msgs.getMsg('announce_rate', [valueAsPercent]);
578 break;
579 case cvox.AbstractTts.PITCH:
580 announcement = Msgs.getMsg('announce_pitch', [valueAsPercent]);
581 break;
582 case cvox.AbstractTts.VOLUME:
583 announcement = Msgs.getMsg('announce_volume', [valueAsPercent]);
584 break;
585 }
586 if (announcement) {
587 cvox.ChromeVox.tts.speak(
588 announcement, cvox.QueueMode.FLUSH,
589 cvox.AbstractTts.PERSONALITY_ANNOTATION);
590 }
591 },
592
593 /**
594 * Navigate to the given range - it both sets the range and outputs it.
595 * @param {!cursors.Range} range The new range.
596 * @private
597 */
598 navigateToRange_: function(range) {
599 // TODO(dtseng): Figure out what it means to focus a range.
600 var actionNode = range.start.node;
601 if (actionNode.role == RoleType.inlineTextBox)
602 actionNode = actionNode.parent;
603
604 // Iframes, when focused, causes the child webArea to fire focus event.
605 // This can result in getting stuck when navigating backward.
606 if (actionNode.role != RoleType.iframe && !actionNode.state.focused)
607 actionNode.focus();
608
609 var prevRange = this.currentRange_;
610 this.setCurrentRange(range);
611
612 new Output().withSpeechAndBraille(
613 range, prevRange, Output.EventType.NAVIGATE)
614 .withQueueMode(cvox.QueueMode.FLUSH)
615 .go();
616 },
617
618 /**
619 * Handles key down events. 543 * Handles key down events.
620 * @param {Event} evt The key down event to process. 544 * @param {Event} evt The key down event to process.
621 * @return {boolean} True if the default action should be performed. 545 * @return {boolean} True if the default action should be performed.
622 */ 546 */
623 onKeyDown: function(evt) { 547 onKeyDown: function(evt) {
624 evt.stickyMode = cvox.ChromeVox.isStickyModeOn() && cvox.ChromeVox.isActive; 548 evt.stickyMode = cvox.ChromeVox.isStickyModeOn() && cvox.ChromeVox.isActive;
625 if (cvox.ChromeVox.passThroughMode) 549 if (cvox.ChromeVox.passThroughMode)
626 return false; 550 return false;
627 551
628 if (this.mode_ != ChromeVoxMode.CLASSIC && 552 if (this.mode_ != ChromeVoxMode.CLASSIC &&
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
666 * @param {!cvox.BrailleKeyEvent} evt 590 * @param {!cvox.BrailleKeyEvent} evt
667 * @param {!cvox.NavBraille} content 591 * @param {!cvox.NavBraille} content
668 * @return {boolean} True if evt was processed. 592 * @return {boolean} True if evt was processed.
669 */ 593 */
670 onBrailleKeyEvent: function(evt, content) { 594 onBrailleKeyEvent: function(evt, content) {
671 if (this.mode_ === ChromeVoxMode.CLASSIC) 595 if (this.mode_ === ChromeVoxMode.CLASSIC)
672 return false; 596 return false;
673 597
674 switch (evt.command) { 598 switch (evt.command) {
675 case cvox.BrailleKeyCommand.PAN_LEFT: 599 case cvox.BrailleKeyCommand.PAN_LEFT:
676 this.onGotCommand('previousObject'); 600 this.onGotCommand('previousElement');
677 break; 601 break;
678 case cvox.BrailleKeyCommand.PAN_RIGHT: 602 case cvox.BrailleKeyCommand.PAN_RIGHT:
679 this.onGotCommand('nextObject'); 603 this.onGotCommand('nextElement');
680 break; 604 break;
681 case cvox.BrailleKeyCommand.LINE_UP: 605 case cvox.BrailleKeyCommand.LINE_UP:
682 this.onGotCommand('previousLine'); 606 this.onGotCommand('previousLine');
683 break; 607 break;
684 case cvox.BrailleKeyCommand.LINE_DOWN: 608 case cvox.BrailleKeyCommand.LINE_DOWN:
685 this.onGotCommand('nextLine'); 609 this.onGotCommand('nextLine');
686 break; 610 break;
687 case cvox.BrailleKeyCommand.TOP: 611 case cvox.BrailleKeyCommand.TOP:
688 this.onGotCommand('jumpToTop'); 612 this.onGotCommand('goToBeginning');
689 break; 613 break;
690 case cvox.BrailleKeyCommand.BOTTOM: 614 case cvox.BrailleKeyCommand.BOTTOM:
691 this.onGotCommand('jumpToBottom'); 615 this.onGotCommand('goToEnd');
692 break; 616 break;
693 case cvox.BrailleKeyCommand.ROUTING: 617 case cvox.BrailleKeyCommand.ROUTING:
694 this.brailleRoutingCommand_( 618 this.brailleRoutingCommand_(
695 content.text, 619 content.text,
696 // Cast ok since displayPosition is always defined in this case. 620 // Cast ok since displayPosition is always defined in this case.
697 /** @type {number} */ (evt.displayPosition)); 621 /** @type {number} */ (evt.displayPosition));
698 break; 622 break;
699 default: 623 default:
700 return false; 624 return false;
701 } 625 }
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
792 target: 'next', 716 target: 'next',
793 isClassicEnabled: isClassicEnabled 717 isClassicEnabled: isClassicEnabled
794 }); 718 });
795 } else if (action == 'onCommand') { 719 } else if (action == 'onCommand') {
796 this.onGotCommand(msg['command']); 720 this.onGotCommand(msg['command']);
797 } else if (action == 'flushNextUtterance') { 721 } else if (action == 'flushNextUtterance') {
798 Output.flushNextSpeechUtterance(); 722 Output.flushNextSpeechUtterance();
799 } 723 }
800 break; 724 break;
801 } 725 }
802 }, 726 }
803
804 /**
805 * Restore the range to the last range that was *not* in the ChromeVox
806 * panel. This is used when the ChromeVox Panel closes.
807 */
808 restoreCurrentRange: function() {
809 if (this.savedRange_) {
810 var containingWebView = this.savedRange_.start.node;
811 while (containingWebView && containingWebView.role != RoleType.webView)
812 containingWebView = containingWebView.parent;
813 if (containingWebView)
814 containingWebView.focus();
815
816 this.navigateToRange_(this.savedRange_);
817 this.savedRange_ = null;
818 }
819 },
820 }; 727 };
821 728
822 /** 729 /**
823 * Converts a list of globs, as used in the extension manifest, to a regular 730 * Converts a list of globs, as used in the extension manifest, to a regular
824 * expression that matches if and only if any of the globs in the list matches. 731 * expression that matches if and only if any of the globs in the list matches.
825 * @param {!Array<string>} globs 732 * @param {!Array<string>} globs
826 * @return {!RegExp} 733 * @return {!RegExp}
827 * @private 734 * @private
828 */ 735 */
829 Background.globsToRegExp_ = function(globs) { 736 Background.globsToRegExp_ = function(globs) {
830 return new RegExp('^(' + globs.map(function(glob) { 737 return new RegExp('^(' + globs.map(function(glob) {
831 return glob.replace(/[.+^$(){}|[\]\\]/g, '\\$&') 738 return glob.replace(/[.+^$(){}|[\]\\]/g, '\\$&')
832 .replace(/\*/g, '.*') 739 .replace(/\*/g, '.*')
833 .replace(/\?/g, '.'); 740 .replace(/\?/g, '.');
834 }).join('|') + ')$'); 741 }).join('|') + ')$');
835 }; 742 };
836 743
837 /** @type {Background} */ 744 /** @type {Background} */
838 global.backgroundObj = new Background(); 745 global.backgroundObj = new Background();
839 746
840 }); // goog.scope 747 }); // goog.scope
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698