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

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

Issue 2943193002: Run clang-format on .js files in c/b/r/chromeos/chromevox (Closed)
Patch Set: Created 3 years, 6 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');
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
86 /** @type {!cvox.AbstractEarcons} @private */ 86 /** @type {!cvox.AbstractEarcons} @private */
87 this.classicEarcons_ = cvox.ChromeVox.earcons || new cvox.ClassicEarcons(); 87 this.classicEarcons_ = cvox.ChromeVox.earcons || new cvox.ClassicEarcons();
88 88
89 /** @type {!cvox.AbstractEarcons} @private */ 89 /** @type {!cvox.AbstractEarcons} @private */
90 this.nextEarcons_ = new NextEarcons(); 90 this.nextEarcons_ = new NextEarcons();
91 91
92 // Turn cvox.ChromeVox.earcons into a getter that returns either the 92 // Turn cvox.ChromeVox.earcons into a getter that returns either the
93 // Next earcons or the Classic earcons depending on the current mode. 93 // Next earcons or the Classic earcons depending on the current mode.
94 Object.defineProperty(cvox.ChromeVox, 'earcons', { 94 Object.defineProperty(cvox.ChromeVox, 'earcons', {
95 get: (function() { 95 get: (function() {
96 if (this.mode === ChromeVoxMode.FORCE_NEXT || 96 if (this.mode === ChromeVoxMode.FORCE_NEXT ||
97 this.mode === ChromeVoxMode.NEXT) { 97 this.mode === ChromeVoxMode.NEXT) {
98 return this.nextEarcons_; 98 return this.nextEarcons_;
99 } else { 99 } else {
100 return this.classicEarcons_; 100 return this.classicEarcons_;
101 } 101 }
102 }).bind(this) 102 }).bind(this)
103 }); 103 });
104 104
105 if (cvox.ChromeVox.isChromeOS) { 105 if (cvox.ChromeVox.isChromeOS) {
106 Object.defineProperty(cvox.ChromeVox, 'modKeyStr', { 106 Object.defineProperty(cvox.ChromeVox, 'modKeyStr', {
107 get: function() { 107 get: function() {
108 return (this.mode == ChromeVoxMode.CLASSIC || 108 return (this.mode == ChromeVoxMode.CLASSIC ||
109 this.mode == ChromeVoxMode.CLASSIC_COMPAT) ? 109 this.mode == ChromeVoxMode.CLASSIC_COMPAT) ?
110 'Search+Shift' : 'Search'; 110 'Search+Shift' :
111 'Search';
111 }.bind(this) 112 }.bind(this)
112 }); 113 });
113 114
114 Object.defineProperty(cvox.ChromeVox, 'typingEcho', { 115 Object.defineProperty(cvox.ChromeVox, 'typingEcho', {
115 get: function() { 116 get: function() {
116 return parseInt(localStorage['typingEcho'], 10); 117 return parseInt(localStorage['typingEcho'], 10);
117 }.bind(this), 118 }.bind(this),
118 set: function(v) { 119 set: function(v) {
119 localStorage['typingEcho'] = v; 120 localStorage['typingEcho'] = v;
120 }.bind(this) 121 }.bind(this)
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
167 this.focusRecoveryMap_ = new WeakMap(); 168 this.focusRecoveryMap_ = new WeakMap();
168 169
169 chrome.automation.getDesktop(function(desktop) { 170 chrome.automation.getDesktop(function(desktop) {
170 /** @type {string} */ 171 /** @type {string} */
171 this.chromeChannel_ = desktop.chromeChannel; 172 this.chromeChannel_ = desktop.chromeChannel;
172 }.bind(this)); 173 }.bind(this));
173 174
174 // Record a metric with the mode we're in on startup. 175 // Record a metric with the mode we're in on startup.
175 var useNext = localStorage['useClassic'] != 'true'; 176 var useNext = localStorage['useClassic'] != 'true';
176 chrome.metricsPrivate.recordValue( 177 chrome.metricsPrivate.recordValue(
177 { metricName: 'Accessibility.CrosChromeVoxNext', 178 {
179 metricName: 'Accessibility.CrosChromeVoxNext',
178 type: chrome.metricsPrivate.MetricTypeType.HISTOGRAM_LINEAR, 180 type: chrome.metricsPrivate.MetricTypeType.HISTOGRAM_LINEAR,
179 min: 1, // According to histogram.h, this should be 1 for enums. 181 min: 1, // According to histogram.h, this should be 1 for enums.
180 max: 2, // Maximum should be exclusive. 182 max: 2, // Maximum should be exclusive.
181 buckets: 3 }, // Number of buckets: 0, 1 and overflowing 2. 183 buckets: 3
184 }, // Number of buckets: 0, 1 and overflowing 2.
182 useNext ? 1 : 0); 185 useNext ? 1 : 0);
183 }; 186 };
184 187
185 /** 188 /**
186 * Map from gesture names (AXGesture defined in ui/accessibility/ax_enums.idl) 189 * Map from gesture names (AXGesture defined in ui/accessibility/ax_enums.idl)
187 * to commands when in Classic mode. 190 * to commands when in Classic mode.
188 * @type {Object<string, string>} 191 * @type {Object<string, string>}
189 * @const 192 * @const
190 */ 193 */
191 Background.GESTURE_CLASSIC_COMMAND_MAP = { 194 Background.GESTURE_CLASSIC_COMMAND_MAP = {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
238 }); 241 });
239 } else { 242 } else {
240 target = this.getCurrentRange().start.node; 243 target = this.getCurrentRange().start.node;
241 } 244 }
242 245
243 if (!target) 246 if (!target)
244 return useNext ? ChromeVoxMode.FORCE_NEXT : ChromeVoxMode.CLASSIC; 247 return useNext ? ChromeVoxMode.FORCE_NEXT : ChromeVoxMode.CLASSIC;
245 248
246 // Closure complains, but clearly, |target| is not null. 249 // Closure complains, but clearly, |target| is not null.
247 var topLevelRoot = 250 var topLevelRoot =
248 AutomationUtil.getTopLevelRoot(/** @type {!AutomationNode} */(target)); 251 AutomationUtil.getTopLevelRoot(/** @type {!AutomationNode} */ (target));
249 if (!topLevelRoot) 252 if (!topLevelRoot)
250 return useNext ? ChromeVoxMode.FORCE_NEXT : 253 return useNext ? ChromeVoxMode.FORCE_NEXT : ChromeVoxMode.CLASSIC_COMPAT;
251 ChromeVoxMode.CLASSIC_COMPAT;
252 254
253 var docUrl = topLevelRoot.docUrl || ''; 255 var docUrl = topLevelRoot.docUrl || '';
254 var nextSite = this.isWhitelistedForNext_(docUrl); 256 var nextSite = this.isWhitelistedForNext_(docUrl);
255 var classicCompat = 257 var classicCompat = this.isWhitelistedForClassicCompat_(docUrl);
256 this.isWhitelistedForClassicCompat_(docUrl);
257 if (classicCompat && !useNext) 258 if (classicCompat && !useNext)
258 return ChromeVoxMode.CLASSIC_COMPAT; 259 return ChromeVoxMode.CLASSIC_COMPAT;
259 else if (nextSite) 260 else if (nextSite)
260 return ChromeVoxMode.NEXT; 261 return ChromeVoxMode.NEXT;
261 else if (!useNext) 262 else if (!useNext)
262 return ChromeVoxMode.CLASSIC; 263 return ChromeVoxMode.CLASSIC;
263 else 264 else
264 return ChromeVoxMode.FORCE_NEXT; 265 return ChromeVoxMode.FORCE_NEXT;
265 }, 266 },
266 267
(...skipping 16 matching lines...) Expand all
283 284
284 // Classic modes do not use the new focus highlight. 285 // Classic modes do not use the new focus highlight.
285 if (newMode == ChromeVoxMode.CLASSIC) 286 if (newMode == ChromeVoxMode.CLASSIC)
286 chrome.accessibilityPrivate.setFocusRing([]); 287 chrome.accessibilityPrivate.setFocusRing([]);
287 288
288 // Switch on/off content scripts. 289 // Switch on/off content scripts.
289 // note that |this.currentRange_| can *change* because the request is 290 // note that |this.currentRange_| can *change* because the request is
290 // async. Save it to ensure we're looking at the currentRange at this moment 291 // async. Save it to ensure we're looking at the currentRange at this moment
291 // in time. 292 // in time.
292 var cur = this.currentRange_; 293 var cur = this.currentRange_;
293 chrome.tabs.query({active: true, 294 chrome.tabs.query({active: true, lastFocusedWindow: true}, function(tabs) {
294 lastFocusedWindow: true}, function(tabs) {
295 if (newMode == ChromeVoxMode.CLASSIC) { 295 if (newMode == ChromeVoxMode.CLASSIC) {
296 // Generally, we don't want to inject classic content scripts as it is 296 // Generally, we don't want to inject classic content scripts as it is
297 // done by the extension system at document load. The exception is when 297 // done by the extension system at document load. The exception is when
298 // we toggle classic on manually as part of a user command. 298 // we toggle classic on manually as part of a user command.
299 if (oldMode == ChromeVoxMode.FORCE_NEXT) { 299 if (oldMode == ChromeVoxMode.FORCE_NEXT) {
300 cvox.ChromeVox.injectChromeVoxIntoTabs(tabs); 300 cvox.ChromeVox.injectChromeVoxIntoTabs(tabs);
301 } 301 }
302 } else if (newMode === ChromeVoxMode.FORCE_NEXT) { 302 } else if (newMode === ChromeVoxMode.FORCE_NEXT) {
303 this.disableClassicChromeVox_(); 303 this.disableClassicChromeVox_();
304 } else { 304 } else {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
355 chrome.metricsPrivate.recordUserAction( 355 chrome.metricsPrivate.recordUserAction(
356 'Accessibility.ChromeVox.ToggleNextOff'); 356 'Accessibility.ChromeVox.ToggleNextOff');
357 } 357 }
358 358
359 localStorage['useClassic'] = !useNext; 359 localStorage['useClassic'] = !useNext;
360 if (useNext) 360 if (useNext)
361 this.setCurrentRangeToFocus_(); 361 this.setCurrentRangeToFocus_();
362 else 362 else
363 this.setCurrentRange(null); 363 this.setCurrentRange(null);
364 364
365 var announce = Msgs.getMsg(useNext ? 365 var announce =
366 'switch_to_next' : 'switch_to_classic'); 366 Msgs.getMsg(useNext ? 'switch_to_next' : 'switch_to_classic');
367 cvox.ChromeVox.tts.speak( 367 cvox.ChromeVox.tts.speak(
368 announce, cvox.QueueMode.FLUSH, {doNotInterrupt: true}); 368 announce, cvox.QueueMode.FLUSH, {doNotInterrupt: true});
369 369
370 // If the new mode is Classic, return false now so we don't announce 370 // If the new mode is Classic, return false now so we don't announce
371 // anything more. 371 // anything more.
372 return useNext; 372 return useNext;
373 }, 373 },
374 374
375 /** 375 /**
376 * @override 376 * @override
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
432 opt_focus = opt_focus === undefined ? true : opt_focus; 432 opt_focus = opt_focus === undefined ? true : opt_focus;
433 opt_speechProps = opt_speechProps || {}; 433 opt_speechProps = opt_speechProps || {};
434 var prevRange = this.currentRange_; 434 var prevRange = this.currentRange_;
435 if (opt_focus) 435 if (opt_focus)
436 this.setFocusToRange_(range, prevRange); 436 this.setFocusToRange_(range, prevRange);
437 437
438 this.setCurrentRange(range); 438 this.setCurrentRange(range);
439 439
440 var o = new Output(); 440 var o = new Output();
441 var selectedRange; 441 var selectedRange;
442 if (this.pageSel_ && 442 if (this.pageSel_ && this.pageSel_.isValid() && range.isValid()) {
443 this.pageSel_.isValid() &&
444 range.isValid()) {
445 // Compute the direction of the endpoints of each range. 443 // Compute the direction of the endpoints of each range.
446 444
447 // Casts are ok because isValid checks node start and end nodes are 445 // Casts are ok because isValid checks node start and end nodes are
448 // non-null; Closure just doesn't eval enough to see it. 446 // non-null; Closure just doesn't eval enough to see it.
449 var startDir = 447 var startDir = AutomationUtil.getDirection(
450 AutomationUtil.getDirection(this.pageSel_.start.node, 448 this.pageSel_.start.node,
451 /** @type {!AutomationNode} */ (range.start.node)); 449 /** @type {!AutomationNode} */ (range.start.node));
452 var endDir = 450 var endDir = AutomationUtil.getDirection(
453 AutomationUtil.getDirection(this.pageSel_.end.node, 451 this.pageSel_.end.node,
454 /** @type {!AutomationNode} */ (range.end.node)); 452 /** @type {!AutomationNode} */ (range.end.node));
455 453
456 // Selection across roots isn't supported. 454 // Selection across roots isn't supported.
457 var pageRootStart = this.pageSel_.start.node.root; 455 var pageRootStart = this.pageSel_.start.node.root;
458 var pageRootEnd = this.pageSel_.end.node.root; 456 var pageRootEnd = this.pageSel_.end.node.root;
459 var curRootStart = range.start.node.root; 457 var curRootStart = range.start.node.root;
460 var curRootEnd = range.end.node.root; 458 var curRootEnd = range.end.node.root;
461 459
462 // Disallow crossing over the start of the page selection and roots. 460 // Disallow crossing over the start of the page selection and roots.
463 if (startDir == Dir.BACKWARD || 461 if (startDir == Dir.BACKWARD || pageRootStart != pageRootEnd ||
464 pageRootStart != pageRootEnd || 462 pageRootStart != curRootStart || pageRootEnd != curRootEnd) {
465 pageRootStart != curRootStart ||
466 pageRootEnd != curRootEnd) {
467 o.format('@end_selection'); 463 o.format('@end_selection');
468 this.pageSel_ = null; 464 this.pageSel_ = null;
469 } else { 465 } else {
470 // Expand or shrink requires different feedback. 466 // Expand or shrink requires different feedback.
471 var msg; 467 var msg;
472 if (endDir == Dir.FORWARD && 468 if (endDir == Dir.FORWARD &&
473 (this.pageSel_.end.node != range.end.node || 469 (this.pageSel_.end.node != range.end.node ||
474 this.pageSel_.end.index <= range.end.index)) { 470 this.pageSel_.end.index <= range.end.index)) {
475 msg = '@selected'; 471 msg = '@selected';
476 } else { 472 } else {
477 msg = '@unselected'; 473 msg = '@unselected';
478 selectedRange = prevRange; 474 selectedRange = prevRange;
479 } 475 }
480 this.pageSel_ = new cursors.Range( 476 this.pageSel_ = new cursors.Range(this.pageSel_.start, range.end);
481 this.pageSel_.start,
482 range.end
483 );
484 if (this.pageSel_) 477 if (this.pageSel_)
485 this.pageSel_.select(); 478 this.pageSel_.select();
486 } 479 }
487 } else { 480 } else {
488 // Ensure we don't select the editable when we first encounter it. 481 // Ensure we don't select the editable when we first encounter it.
489 var lca = null; 482 var lca = null;
490 if (range.start.node && prevRange.start.node) { 483 if (range.start.node && prevRange.start.node) {
491 lca = AutomationUtil.getLeastCommonAncestor(prevRange.start.node, 484 lca = AutomationUtil.getLeastCommonAncestor(
492 range.start.node); 485 prevRange.start.node, range.start.node);
493 } 486 }
494 if (!lca || lca.state[StateType.EDITABLE] || 487 if (!lca || lca.state[StateType.EDITABLE] ||
495 !range.start.node.state[StateType.EDITABLE]) 488 !range.start.node.state[StateType.EDITABLE])
496 range.select(); 489 range.select();
497 } 490 }
498 491
499 o.withRichSpeechAndBraille( 492 o.withRichSpeechAndBraille(
500 selectedRange || range, prevRange, Output.EventType.NAVIGATE) 493 selectedRange || range, prevRange, Output.EventType.NAVIGATE)
501 .withQueueMode(cvox.QueueMode.FLUSH); 494 .withQueueMode(cvox.QueueMode.FLUSH);
502 495
503 if (msg) 496 if (msg)
504 o.format(msg); 497 o.format(msg);
505 498
506 for (var prop in opt_speechProps) 499 for (var prop in opt_speechProps)
507 o.format('!' + prop); 500 o.format('!' + prop);
508 501
509 o.go(); 502 o.go();
510 }, 503 },
511 504
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
566 return true; 559 return true;
567 }, 560 },
568 561
569 /** 562 /**
570 * Returns true if the url should have Classic running. 563 * Returns true if the url should have Classic running.
571 * @return {boolean} 564 * @return {boolean}
572 * @private 565 * @private
573 */ 566 */
574 shouldEnableClassicForUrl_: function(url) { 567 shouldEnableClassicForUrl_: function(url) {
575 return this.mode != ChromeVoxMode.FORCE_NEXT && 568 return this.mode != ChromeVoxMode.FORCE_NEXT &&
576 !this.isBlacklistedForClassic_(url) && 569 !this.isBlacklistedForClassic_(url) && !this.isWhitelistedForNext_(url);
577 !this.isWhitelistedForNext_(url);
578 }, 570 },
579 571
580 /** 572 /**
581 * Compat mode is on if any of the following are true: 573 * Compat mode is on if any of the following are true:
582 * 1. a url is blacklisted for Classic. 574 * 1. a url is blacklisted for Classic.
583 * 2. the current range is not within web content. 575 * 2. the current range is not within web content.
584 * @param {string} url 576 * @param {string} url
585 * @return {boolean} 577 * @return {boolean}
586 */ 578 */
587 isWhitelistedForClassicCompat_: function(url) { 579 isWhitelistedForClassicCompat_: function(url) {
588 return (this.isBlacklistedForClassic_(url) || (this.getCurrentRange() && 580 return (this.isBlacklistedForClassic_(url) ||
589 !this.getCurrentRange().isWebRange() && 581 (this.getCurrentRange() && !this.getCurrentRange().isWebRange() &&
590 this.getCurrentRange().start.node.state[StateType.FOCUSED])) || false; 582 this.getCurrentRange().start.node.state[StateType.FOCUSED])) ||
583 false;
591 }, 584 },
592 585
593 /** 586 /**
594 * @param {string} url 587 * @param {string} url
595 * @return {boolean} 588 * @return {boolean}
596 * @private 589 * @private
597 */ 590 */
598 isBlacklistedForClassic_: function(url) { 591 isBlacklistedForClassic_: function(url) {
599 if (this.classicBlacklistRegExp_.test(url)) 592 if (this.classicBlacklistRegExp_.test(url))
600 return true; 593 return true;
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
659 actionNode = actionNode.parent; 652 actionNode = actionNode.parent;
660 actionNode.doDefault(); 653 actionNode.doDefault();
661 654
662 if (!selectionSpan) 655 if (!selectionSpan)
663 selectionSpan = actionNodeSpan; 656 selectionSpan = actionNodeSpan;
664 657
665 var start = text.getSpanStart(selectionSpan); 658 var start = text.getSpanStart(selectionSpan);
666 var targetPosition = position - start + offset; 659 var targetPosition = position - start + offset;
667 660
668 if (actionNode.state.richlyEditable) { 661 if (actionNode.state.richlyEditable) {
669 chrome.automation.setDocumentSelection( 662 chrome.automation.setDocumentSelection({
670 { anchorObject: actionNode, 663 anchorObject: actionNode,
671 anchorOffset: targetPosition, 664 anchorOffset: targetPosition,
672 focusObject: actionNode, 665 focusObject: actionNode,
673 focusOffset: targetPosition }); 666 focusOffset: targetPosition
667 });
674 } else { 668 } else {
675 actionNode.setSelection(targetPosition, targetPosition); 669 actionNode.setSelection(targetPosition, targetPosition);
676 } 670 }
677 }, 671 },
678 672
679 /** 673 /**
680 * @param {Object} msg A message sent from a content script. 674 * @param {Object} msg A message sent from a content script.
681 * @param {Port} port 675 * @param {Port} port
682 * @private 676 * @private
683 */ 677 */
684 onMessage_: function(msg, port) { 678 onMessage_: function(msg, port) {
685 var target = msg['target']; 679 var target = msg['target'];
686 var action = msg['action']; 680 var action = msg['action'];
687 681
688 switch (target) { 682 switch (target) {
689 case 'next': 683 case 'next':
690 if (action == 'getIsClassicEnabled') { 684 if (action == 'getIsClassicEnabled') {
691 var url = msg['url']; 685 var url = msg['url'];
692 var isClassicEnabled = this.shouldEnableClassicForUrl_(url); 686 var isClassicEnabled = this.shouldEnableClassicForUrl_(url);
693 port.postMessage({ 687 port.postMessage(
694 target: 'next', 688 {target: 'next', isClassicEnabled: isClassicEnabled});
695 isClassicEnabled: isClassicEnabled
696 });
697 } else if (action == 'enableClassicCompatForUrl') { 689 } else if (action == 'enableClassicCompatForUrl') {
698 var url = msg['url']; 690 var url = msg['url'];
699 this.classicBlacklist_.add(url); 691 this.classicBlacklist_.add(url);
700 if (this.currentRange_ && this.currentRange_.start.node) 692 if (this.currentRange_ && this.currentRange_.start.node)
701 this.setCurrentRange(this.currentRange_); 693 this.setCurrentRange(this.currentRange_);
702 } else if (action == 'onCommand') { 694 } else if (action == 'onCommand') {
703 CommandHandler.onCommand(msg['command']); 695 CommandHandler.onCommand(msg['command']);
704 } else if (action == 'flushNextUtterance') { 696 } else if (action == 'flushNextUtterance') {
705 Output.forceModeForNextSpeechUtterance(cvox.QueueMode.FLUSH); 697 Output.forceModeForNextSpeechUtterance(cvox.QueueMode.FLUSH);
706 } 698 }
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
746 * @param {string} gesture The gesture to handle, based on the AXGesture enum 738 * @param {string} gesture The gesture to handle, based on the AXGesture enum
747 * defined in ui/accessibility/ax_enums.idl 739 * defined in ui/accessibility/ax_enums.idl
748 * @return {boolean} True if this gesture was handled. 740 * @return {boolean} True if this gesture was handled.
749 * @private 741 * @private
750 */ 742 */
751 handleClassicGesture_: function(gesture) { 743 handleClassicGesture_: function(gesture) {
752 var command = Background.GESTURE_CLASSIC_COMMAND_MAP[gesture]; 744 var command = Background.GESTURE_CLASSIC_COMMAND_MAP[gesture];
753 if (!command) 745 if (!command)
754 return false; 746 return false;
755 747
756 var msg = { 748 var msg = {'message': 'USER_COMMAND', 'command': command};
757 'message': 'USER_COMMAND',
758 'command': command
759 };
760 cvox.ExtensionBridge.send(msg); 749 cvox.ExtensionBridge.send(msg);
761 return true; 750 return true;
762 }, 751 },
763 752
764 /** @private */ 753 /** @private */
765 setCurrentRangeToFocus_: function() { 754 setCurrentRangeToFocus_: function() {
766 chrome.automation.getFocus(function(focus) { 755 chrome.automation.getFocus(function(focus) {
767 if (focus) 756 if (focus)
768 this.setCurrentRange(cursors.Range.fromNode(focus)); 757 this.setCurrentRange(cursors.Range.fromNode(focus));
769 else 758 else
770 this.setCurrentRange(null); 759 this.setCurrentRange(null);
771 }.bind(this)); 760 }.bind(this));
772 }, 761 },
773 762
774 /** 763 /**
775 * @param {!cursors.Range} range 764 * @param {!cursors.Range} range
776 * @param {cursors.Range} prevRange 765 * @param {cursors.Range} prevRange
777 * @private 766 * @private
778 */ 767 */
779 setFocusToRange_: function(range, prevRange) { 768 setFocusToRange_: function(range, prevRange) {
780 var start = range.start.node; 769 var start = range.start.node;
781 var end = range.end.node; 770 var end = range.end.node;
782 771
783 // First, see if we've crossed a root. Remove once webview handles focus 772 // First, see if we've crossed a root. Remove once webview handles focus
784 // correctly. 773 // correctly.
785 if (prevRange && prevRange.start.node && start) { 774 if (prevRange && prevRange.start.node && start) {
786 var entered = AutomationUtil.getUniqueAncestors( 775 var entered =
787 prevRange.start.node, start); 776 AutomationUtil.getUniqueAncestors(prevRange.start.node, start);
788 var embeddedObject = entered.find(function(f) { 777 var embeddedObject = entered.find(function(f) {
789 return f.role == RoleType.EMBEDDED_OBJECT; }); 778 return f.role == RoleType.EMBEDDED_OBJECT;
779 });
790 if (embeddedObject && !embeddedObject.state[StateType.FOCUSED]) 780 if (embeddedObject && !embeddedObject.state[StateType.FOCUSED])
791 embeddedObject.focus(); 781 embeddedObject.focus();
792 } 782 }
793 783
794 if (start.state[StateType.FOCUSED] || end.state[StateType.FOCUSED]) 784 if (start.state[StateType.FOCUSED] || end.state[StateType.FOCUSED])
795 return; 785 return;
796 786
797 var isFocusableLinkOrControl = function(node) { 787 var isFocusableLinkOrControl = function(node) {
798 return node.state[StateType.FOCUSABLE] && 788 return node.state[StateType.FOCUSABLE] &&
799 AutomationPredicate.linkOrControl(node); 789 AutomationPredicate.linkOrControl(node);
800 }; 790 };
801 791
802 // Next, try to focus the start or end node. 792 // Next, try to focus the start or end node.
803 if (!AutomationPredicate.structuralContainer(start) && 793 if (!AutomationPredicate.structuralContainer(start) &&
804 start.state[StateType.FOCUSABLE]) { 794 start.state[StateType.FOCUSABLE]) {
805 if (!start.state[StateType.FOCUSED]) 795 if (!start.state[StateType.FOCUSED])
806 start.focus(); 796 start.focus();
807 return; 797 return;
808 } else if (!AutomationPredicate.structuralContainer(end) && 798 } else if (
799 !AutomationPredicate.structuralContainer(end) &&
809 end.state[StateType.FOCUSABLE]) { 800 end.state[StateType.FOCUSABLE]) {
810 if (!end.state[StateType.FOCUSED]) 801 if (!end.state[StateType.FOCUSED])
811 end.focus(); 802 end.focus();
812 return; 803 return;
813 } 804 }
814 805
815 // If a common ancestor of |start| and |end| is a link, focus that. 806 // If a common ancestor of |start| and |end| is a link, focus that.
816 var ancestor = AutomationUtil.getLeastCommonAncestor(start, end); 807 var ancestor = AutomationUtil.getLeastCommonAncestor(start, end);
817 while (ancestor && ancestor.root == start.root) { 808 while (ancestor && ancestor.root == start.root) {
818 if (isFocusableLinkOrControl(ancestor)) { 809 if (isFocusableLinkOrControl(ancestor)) {
(...skipping 13 matching lines...) Expand all
832 }; 823 };
833 824
834 /** 825 /**
835 * Converts a list of globs, as used in the extension manifest, to a regular 826 * Converts a list of globs, as used in the extension manifest, to a regular
836 * expression that matches if and only if any of the globs in the list matches. 827 * expression that matches if and only if any of the globs in the list matches.
837 * @param {!Array<string>} globs 828 * @param {!Array<string>} globs
838 * @return {!RegExp} 829 * @return {!RegExp}
839 * @private 830 * @private
840 */ 831 */
841 Background.globsToRegExp_ = function(globs) { 832 Background.globsToRegExp_ = function(globs) {
842 return new RegExp('^(' + globs.map(function(glob) { 833 return new RegExp(
843 return glob.replace(/[.+^$(){}|[\]\\]/g, '\\$&') 834 '^(' +
844 .replace(/\*/g, '.*') 835 globs
845 .replace(/\?/g, '.'); 836 .map(function(glob) {
846 }).join('|') + ')$'); 837 return glob.replace(/[.+^$(){}|[\]\\]/g, '\\$&')
838 .replace(/\*/g, '.*')
839 .replace(/\?/g, '.');
840 })
841 .join('|') +
842 ')$');
847 }; 843 };
848 844
849 new Background(); 845 new Background();
850 846
851 }); // goog.scope 847 }); // goog.scope
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698