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'); |
(...skipping 20 matching lines...) Expand all Loading... |
31 goog.require('cvox.ChromeVoxEditableTextBase'); | 31 goog.require('cvox.ChromeVoxEditableTextBase'); |
32 goog.require('cvox.ClassicEarcons'); | 32 goog.require('cvox.ClassicEarcons'); |
33 goog.require('cvox.ExtensionBridge'); | 33 goog.require('cvox.ExtensionBridge'); |
34 goog.require('cvox.NavBraille'); | 34 goog.require('cvox.NavBraille'); |
35 | 35 |
36 goog.scope(function() { | 36 goog.scope(function() { |
37 var AutomationNode = chrome.automation.AutomationNode; | 37 var AutomationNode = chrome.automation.AutomationNode; |
38 var Dir = constants.Dir; | 38 var Dir = constants.Dir; |
39 var EventType = chrome.automation.EventType; | 39 var EventType = chrome.automation.EventType; |
40 var RoleType = chrome.automation.RoleType; | 40 var RoleType = chrome.automation.RoleType; |
| 41 var StateType = chrome.automation.StateType; |
41 | 42 |
42 /** | 43 /** |
43 * ChromeVox2 background page. | 44 * ChromeVox2 background page. |
44 * @constructor | 45 * @constructor |
45 * @extends {ChromeVoxState} | 46 * @extends {ChromeVoxState} |
46 */ | 47 */ |
47 Background = function() { | 48 Background = function() { |
48 ChromeVoxState.call(this); | 49 ChromeVoxState.call(this); |
49 | 50 |
50 /** | 51 /** |
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
409 if (oldMode != newMode) { | 410 if (oldMode != newMode) { |
410 this.onModeChanged_(newMode, oldMode); | 411 this.onModeChanged_(newMode, oldMode); |
411 this.mode_ = newMode; | 412 this.mode_ = newMode; |
412 } | 413 } |
413 | 414 |
414 if (this.currentRange_) { | 415 if (this.currentRange_) { |
415 var start = this.currentRange_.start.node; | 416 var start = this.currentRange_.start.node; |
416 start.makeVisible(); | 417 start.makeVisible(); |
417 | 418 |
418 var root = start.root; | 419 var root = start.root; |
419 if (!root || root.role == RoleType.desktop) | 420 if (!root || root.role == RoleType.DESKTOP) |
420 return; | 421 return; |
421 | 422 |
422 var position = {}; | 423 var position = {}; |
423 var loc = start.location; | 424 var loc = start.location; |
424 position.x = loc.left + loc.width / 2; | 425 position.x = loc.left + loc.width / 2; |
425 position.y = loc.top + loc.height / 2; | 426 position.y = loc.top + loc.height / 2; |
426 var url = root.docUrl; | 427 var url = root.docUrl; |
427 url = url.substring(0, url.indexOf('#')) || url; | 428 url = url.substring(0, url.indexOf('#')) || url; |
428 cvox.ChromeVox.position[url] = position; | 429 cvox.ChromeVox.position[url] = position; |
429 } | 430 } |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
492 if (this.pageSel_) | 493 if (this.pageSel_) |
493 this.pageSel_.select(); | 494 this.pageSel_.select(); |
494 } | 495 } |
495 } else { | 496 } else { |
496 // Ensure we don't select the editable when we first encounter it. | 497 // Ensure we don't select the editable when we first encounter it. |
497 var lca = null; | 498 var lca = null; |
498 if (range.start.node && prevRange.start.node) { | 499 if (range.start.node && prevRange.start.node) { |
499 lca = AutomationUtil.getLeastCommonAncestor(prevRange.start.node, | 500 lca = AutomationUtil.getLeastCommonAncestor(prevRange.start.node, |
500 range.start.node); | 501 range.start.node); |
501 } | 502 } |
502 if (!lca || lca.state.editable || !range.start.node.state.editable) | 503 if (!lca || lca.state[StateType.EDITABLE] || |
| 504 !range.start.node.state[StateType.EDITABLE]) |
503 range.select(); | 505 range.select(); |
504 } | 506 } |
505 | 507 |
506 o.withRichSpeechAndBraille( | 508 o.withRichSpeechAndBraille( |
507 selectedRange || range, prevRange, Output.EventType.NAVIGATE) | 509 selectedRange || range, prevRange, Output.EventType.NAVIGATE) |
508 .withQueueMode(cvox.QueueMode.FLUSH); | 510 .withQueueMode(cvox.QueueMode.FLUSH); |
509 | 511 |
510 if (msg) | 512 if (msg) |
511 o.format(msg); | 513 o.format(msg); |
512 | 514 |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
588 /** | 590 /** |
589 * Compat mode is on if any of the following are true: | 591 * Compat mode is on if any of the following are true: |
590 * 1. a url is blacklisted for Classic. | 592 * 1. a url is blacklisted for Classic. |
591 * 2. the current range is not within web content. | 593 * 2. the current range is not within web content. |
592 * @param {string} url | 594 * @param {string} url |
593 * @return {boolean} | 595 * @return {boolean} |
594 */ | 596 */ |
595 isWhitelistedForClassicCompat_: function(url) { | 597 isWhitelistedForClassicCompat_: function(url) { |
596 return this.isBlacklistedForClassic_(url) || (this.getCurrentRange() && | 598 return this.isBlacklistedForClassic_(url) || (this.getCurrentRange() && |
597 !this.getCurrentRange().isWebRange() && | 599 !this.getCurrentRange().isWebRange() && |
598 this.getCurrentRange().start.node.state.focused); | 600 this.getCurrentRange().start.node.state[StateType.FOCUSED]) |
599 }, | 601 }, |
600 | 602 |
601 /** | 603 /** |
602 * @param {string} url | 604 * @param {string} url |
603 * @return {boolean} | 605 * @return {boolean} |
604 * @private | 606 * @private |
605 */ | 607 */ |
606 isBlacklistedForClassic_: function(url) { | 608 isBlacklistedForClassic_: function(url) { |
607 if (this.classicBlacklistRegExp_.test(url)) | 609 if (this.classicBlacklistRegExp_.test(url)) |
608 return true; | 610 return true; |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
665 } else if (span instanceof Output.NodeSpan) { | 667 } else if (span instanceof Output.NodeSpan) { |
666 if (!actionNodeSpan || | 668 if (!actionNodeSpan || |
667 text.getSpanLength(span) <= text.getSpanLength(actionNodeSpan)) { | 669 text.getSpanLength(span) <= text.getSpanLength(actionNodeSpan)) { |
668 actionNodeSpan = span; | 670 actionNodeSpan = span; |
669 } | 671 } |
670 } | 672 } |
671 }); | 673 }); |
672 if (!actionNodeSpan) | 674 if (!actionNodeSpan) |
673 return; | 675 return; |
674 var actionNode = actionNodeSpan.node; | 676 var actionNode = actionNodeSpan.node; |
675 if (actionNode.role === RoleType.inlineTextBox) | 677 if (actionNode.role === RoleType.INLINE_TEXT_BOX) |
676 actionNode = actionNode.parent; | 678 actionNode = actionNode.parent; |
677 actionNode.doDefault(); | 679 actionNode.doDefault(); |
678 if (selectionSpan) { | 680 if (selectionSpan) { |
679 var start = text.getSpanStart(selectionSpan); | 681 var start = text.getSpanStart(selectionSpan); |
680 var targetPosition = position - start; | 682 var targetPosition = position - start; |
681 actionNode.setSelection(targetPosition, targetPosition); | 683 actionNode.setSelection(targetPosition, targetPosition); |
682 } | 684 } |
683 }, | 685 }, |
684 | 686 |
685 /** | 687 /** |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
785 setFocusToRange_: function(range, prevRange) { | 787 setFocusToRange_: function(range, prevRange) { |
786 var start = range.start.node; | 788 var start = range.start.node; |
787 var end = range.end.node; | 789 var end = range.end.node; |
788 | 790 |
789 // First, see if we've crossed a root. Remove once webview handles focus | 791 // First, see if we've crossed a root. Remove once webview handles focus |
790 // correctly. | 792 // correctly. |
791 if (prevRange && prevRange.start.node && start) { | 793 if (prevRange && prevRange.start.node && start) { |
792 var entered = AutomationUtil.getUniqueAncestors( | 794 var entered = AutomationUtil.getUniqueAncestors( |
793 prevRange.start.node, start); | 795 prevRange.start.node, start); |
794 var embeddedObject = entered.find(function(f) { | 796 var embeddedObject = entered.find(function(f) { |
795 return f.role == RoleType.embeddedObject; }); | 797 return f.role == RoleType.EMBEDDED_OBJECT; }); |
796 if (embeddedObject && !embeddedObject.state.focused) | 798 if (embeddedObject && !embeddedObject.state[StateType.FOCUSED]) |
797 embeddedObject.focus(); | 799 embeddedObject.focus(); |
798 } | 800 } |
799 | 801 |
800 if (start.state.focused || end.state.focused) | 802 if (start.state[StateType.FOCUSED] || end.state[StateType.FOCUSED]) |
801 return; | 803 return; |
802 | 804 |
803 var isFocusableLinkOrControl = function(node) { | 805 var isFocusableLinkOrControl = function(node) { |
804 return node.state.focusable && | 806 return node.state[StateType.FOCUSABLE] && |
805 AutomationPredicate.linkOrControl(node); | 807 AutomationPredicate.linkOrControl(node); |
806 }; | 808 }; |
807 | 809 |
808 // Next, try to focus the start or end node. | 810 // Next, try to focus the start or end node. |
809 if (!AutomationPredicate.structuralContainer(start) && | 811 if (!AutomationPredicate.structuralContainer(start) && |
810 start.state.focusable) { | 812 start.state[StateType.FOCUSABLE]) { |
811 if (!start.state.focused) | 813 if (!start.state[StateType.FOCUSED]) |
812 start.focus(); | 814 start.focus(); |
813 return; | 815 return; |
814 } else if (!AutomationPredicate.structuralContainer(end) && | 816 } else if (!AutomationPredicate.structuralContainer(end) && |
815 end.state.focusable) { | 817 end.state[StateType.FOCUSABLE]) { |
816 if (!end.state.focused) | 818 if (!end.state[StateType.FOCUSED]) |
817 end.focus(); | 819 end.focus(); |
818 return; | 820 return; |
819 } | 821 } |
820 | 822 |
821 // If a common ancestor of |start| and |end| is a link, focus that. | 823 // If a common ancestor of |start| and |end| is a link, focus that. |
822 var ancestor = AutomationUtil.getLeastCommonAncestor(start, end); | 824 var ancestor = AutomationUtil.getLeastCommonAncestor(start, end); |
823 while (ancestor && ancestor.root == start.root) { | 825 while (ancestor && ancestor.root == start.root) { |
824 if (isFocusableLinkOrControl(ancestor)) { | 826 if (isFocusableLinkOrControl(ancestor)) { |
825 if (!ancestor.state.focused) | 827 if (!ancestor.state[StateType.FOCUSED]) |
826 ancestor.focus(); | 828 ancestor.focus(); |
827 return; | 829 return; |
828 } | 830 } |
829 ancestor = ancestor.parent; | 831 ancestor = ancestor.parent; |
830 } | 832 } |
831 | 833 |
832 // If nothing is focusable, set the sequential focus navigation starting | 834 // If nothing is focusable, set the sequential focus navigation starting |
833 // point, which ensures that the next time you press Tab, you'll reach | 835 // point, which ensures that the next time you press Tab, you'll reach |
834 // the next or previous focusable node from |start|. | 836 // the next or previous focusable node from |start|. |
835 if (!start.state.offscreen) | 837 if (!start.state[StateType.OFFSCREEN]) |
836 start.setSequentialFocusNavigationStartingPoint(); | 838 start.setSequentialFocusNavigationStartingPoint(); |
837 } | 839 } |
838 }; | 840 }; |
839 | 841 |
840 /** | 842 /** |
841 * Converts a list of globs, as used in the extension manifest, to a regular | 843 * Converts a list of globs, as used in the extension manifest, to a regular |
842 * expression that matches if and only if any of the globs in the list matches. | 844 * expression that matches if and only if any of the globs in the list matches. |
843 * @param {!Array<string>} globs | 845 * @param {!Array<string>} globs |
844 * @return {!RegExp} | 846 * @return {!RegExp} |
845 * @private | 847 * @private |
846 */ | 848 */ |
847 Background.globsToRegExp_ = function(globs) { | 849 Background.globsToRegExp_ = function(globs) { |
848 return new RegExp('^(' + globs.map(function(glob) { | 850 return new RegExp('^(' + globs.map(function(glob) { |
849 return glob.replace(/[.+^$(){}|[\]\\]/g, '\\$&') | 851 return glob.replace(/[.+^$(){}|[\]\\]/g, '\\$&') |
850 .replace(/\*/g, '.*') | 852 .replace(/\*/g, '.*') |
851 .replace(/\?/g, '.'); | 853 .replace(/\?/g, '.'); |
852 }).join('|') + ')$'); | 854 }).join('|') + ')$'); |
853 }; | 855 }; |
854 | 856 |
855 new Background(); | 857 new Background(); |
856 | 858 |
857 }); // goog.scope | 859 }); // goog.scope |
OLD | NEW |