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

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

Issue 2079073002: Make ChromeVox Next a setting in options page. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: m Created 4 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/resources/chromeos/chromevox/cvox2/background/background.js
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/background.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/background.js
index 5c5b4dfcd0a3c978021d6a122f9aa5eaa68e0f03..ed1199b8698102efd8a5b59fc950515a1bf94fe8 100644
--- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/background.js
+++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/background.js
@@ -70,13 +70,6 @@ Background = function() {
*/
this.savedRange_ = null;
- /**
- * Which variant of ChromeVox is active.
- * @type {ChromeVoxMode}
- * @private
- */
- this.mode_ = ChromeVoxMode.COMPAT;
-
// Manually bind all functions to |this|.
for (var func in this) {
if (typeof(this[func]) == 'function')
@@ -93,8 +86,8 @@ Background = function() {
// Next earcons or the Classic earcons depending on the current mode.
Object.defineProperty(cvox.ChromeVox, 'earcons', {
get: (function() {
- if (this.mode_ === ChromeVoxMode.FORCE_NEXT ||
- this.mode_ === ChromeVoxMode.NEXT) {
+ if (this.mode === ChromeVoxMode.FORCE_NEXT ||
+ this.mode === ChromeVoxMode.NEXT) {
return this.nextEarcons_;
} else {
return this.classicEarcons_;
@@ -105,7 +98,7 @@ Background = function() {
if (cvox.ChromeVox.isChromeOS) {
Object.defineProperty(cvox.ChromeVox, 'modKeyStr', {
get: function() {
- return (this.mode_ == ChromeVoxMode.CLASSIC || this.mode_ ==
+ return (this.mode == ChromeVoxMode.CLASSIC || this.mode ==
ChromeVoxMode.COMPAT) ?
'Search+Shift' : 'Search';
}.bind(this)
@@ -139,6 +132,11 @@ Background = function() {
/** @type {boolean} @private */
this.inExcursion_ = false;
+ /**
+ * Stores the mode as computed the last time a current range was set.
+ */
+ this.mode_ = ChromeVoxMode.COMPAT;
dmazzoni 2016/06/21 21:21:02 Can you use getMode() here?
David Tseng 2016/06/21 22:41:32 No, because we always need to perform the basic se
+
if (!chrome.accessibilityPrivate.setKeyboardListener)
chrome.accessibilityPrivate.setKeyboardListener = function() {};
@@ -146,6 +144,11 @@ Background = function() {
chrome.accessibilityPrivate.onAccessibilityGesture.addListener(
this.onAccessibilityGesture_);
+ if (localStorage['useNext'] == 'true')
+ this.forceChromeVoxNextActive();
+ else
+ this.onModeChanged_(ChromeVoxMode.COMPAT, ChromeVoxMode.CLASSIC);
dmazzoni 2016/06/21 21:21:02 It'd be nice if you could just call refreshMode()
David Tseng 2016/06/21 22:41:32 new mode and call onModeChanged automatically base
+
Notifications.onStartup();
}};
@@ -196,28 +199,61 @@ Background.prototype = {
* @override
*/
getMode: function() {
- return this.mode_;
+ if (localStorage['useNext'] == 'true')
+ return ChromeVoxMode.FORCE_NEXT;
+
+ var target;
+ if (!this.getCurrentRange()) {
+ chrome.automation.getFocus(function(focus) {
+ target = focus;
+ });
+ } else {
+ target = this.getCurrentRange().start.node;
+ }
+
+ if (!target)
+ return ChromeVoxMode.CLASSIC;
+
+ // Closure complains, but clearly, |target| is not null.
+ var root =
+ AutomationUtil.getTopLevelRoot(/** @type {!AutomationNode} */(target));
+ if (!root)
+ return ChromeVoxMode.COMPAT;
dmazzoni 2016/06/21 21:21:02 nit: wrong indent
David Tseng 2016/06/21 22:41:32 Done.
+ if (this.isWhitelistedForCompat_(root.docUrl))
+ return ChromeVoxMode.COMPAT;
+ else if (this.isWhitelistedForNext_(root.docUrl))
+ return ChromeVoxMode.NEXT;
+ else
+ return ChromeVoxMode.CLASSIC;
},
/**
- * @override
+ * Handles a mode change.
+ * @param {ChromeVoxMode} newMode
+ * @param {ChromeVoxMode} oldMode
+ * @private
*/
- setMode: function(mode, opt_injectClassic) {
+ onModeChanged_: function(newMode, oldMode) {
// Switching key maps potentially affects the key codes that involve
// sequencing. Without resetting this list, potentially stale key codes
// remain. The key codes themselves get pushed in
// cvox.KeySequence.deserialize which gets called by cvox.KeyMap.
cvox.ChromeVox.sequenceSwitchKeyCodes = [];
- if (mode === ChromeVoxMode.CLASSIC || mode === ChromeVoxMode.COMPAT)
- window['prefs'].switchToKeyMap('keymap_classic');
- else
- window['prefs'].switchToKeyMap('keymap_next');
+ if (window['prefs']) {
+ if (newMode === ChromeVoxMode.CLASSIC || newMode === ChromeVoxMode.COMPAT)
+ window['prefs'].switchToKeyMap('keymap_classic');
+ else
+ window['prefs'].switchToKeyMap('keymap_next');
+ }
- if (mode == ChromeVoxMode.CLASSIC) {
+ if (newMode == ChromeVoxMode.CLASSIC) {
if (chrome.commands &&
chrome.commands.onCommand.hasListener(this.onGotCommand))
chrome.commands.onCommand.removeListener(this.onGotCommand);
chrome.accessibilityPrivate.setKeyboardListener(false, false);
+
+ if (cvox.ChromeVox.isChromeOS)
+ chrome.accessibilityPrivate.setFocusRing([]);
} else {
if (chrome.commands &&
!chrome.commands.onCommand.hasListener(this.onGotCommand))
@@ -231,11 +267,11 @@ Background.prototype = {
// in time.
var cur = this.currentRange_;
chrome.tabs.query({active: true}, function(tabs) {
- if (mode === ChromeVoxMode.CLASSIC) {
+ if (newMode === ChromeVoxMode.CLASSIC) {
// Generally, we don't want to inject classic content scripts as it is
// done by the extension system at document load. The exception is when
// we toggle classic on manually as part of a user command.
- if (opt_injectClassic)
+ if (oldMode == ChromeVoxMode.FORCE_NEXT)
cvox.ChromeVox.injectChromeVoxIntoTabs(tabs);
} else {
// When in compat mode, if the focus is within the desktop tree proper,
@@ -249,14 +285,12 @@ Background.prototype = {
// If switching out of a ChromeVox Next mode, make sure we cancel
// the progress loading sound just in case.
- if ((this.mode_ === ChromeVoxMode.NEXT ||
- this.mode_ === ChromeVoxMode.FORCE_NEXT) &&
- this.mode_ != mode) {
+ if (oldMode === ChromeVoxMode.NEXT ||
+ oldMode === ChromeVoxMode.FORCE_NEXT)
cvox.ChromeVox.earcons.cancelEarcon(cvox.Earcon.PAGE_START_LOADING);
- }
- if (mode === ChromeVoxMode.NEXT ||
- mode === ChromeVoxMode.FORCE_NEXT) {
+ if (newMode === ChromeVoxMode.NEXT ||
+ newMode === ChromeVoxMode.FORCE_NEXT) {
(new PanelCommand(PanelCommandType.ENABLE_MENUS)).send();
if (cvox.TabsApiHandler)
cvox.TabsApiHandler.shouldOutputSpeechAndBraille = false;
@@ -265,61 +299,38 @@ Background.prototype = {
if (cvox.TabsApiHandler)
cvox.TabsApiHandler.shouldOutputSpeechAndBraille = true;
}
-
- // If switching to Classic from any automation-API-based mode,
- // clear the focus ring.
- if (mode === ChromeVoxMode.CLASSIC && mode != this.mode_) {
- if (cvox.ChromeVox.isChromeOS)
- chrome.accessibilityPrivate.setFocusRing([]);
- }
-
- // If switching away from Classic to any automation-API-based mode,
- // update the range based on what's focused.
- if (this.mode_ === ChromeVoxMode.CLASSIC && mode != this.mode_) {
- chrome.automation.getFocus((function(focus) {
- if (focus)
- this.setCurrentRange(cursors.Range.fromNode(focus));
- }).bind(this));
- }
-
- this.mode_ = mode;
},
/**
- * Mode refreshes takes into account both |url| and the current ChromeVox
- * range. The latter gets used to decide if the user is or isn't in web
- * content. The focused state also needs to be set for this info to be
- * reliable.
- * @override
+ * Toggles between force next and classic/compat modes.
+ * This toggle automatically handles deciding between classic/compat based on
+ * the start of the current range.
+ * @param {boolean=} opt_setValue Directly set to force next (true) or
+ * classic/compat (false).
+ * @return {boolean} True to announce current position.
*/
- refreshMode: function(node) {
- // Mode changes are based upon the top level web root.
- var root = node.root;
- while (root &&
- root.parent &&
- root.parent.root &&
- root.parent.root.role != RoleType.desktop) {
- root = root.parent.root;
- }
+ toggleNext: function(opt_setValue) {
+ var useNext;
+ if (opt_setValue !== undefined)
+ useNext = opt_setValue;
+ else
+ useNext = localStorage['useNext'] != 'true';
- var url = '';
- if (root && root.role == RoleType.rootWebArea)
- url = root.docUrl;
-
- var mode = this.mode_;
- if (mode != ChromeVoxMode.FORCE_NEXT) {
- if (this.isWhitelistedForNext_(url)) {
- mode = ChromeVoxMode.NEXT;
- } else if (this.isBlacklistedForClassic_(url) || (this.currentRange_ &&
- !this.currentRange_.isWebRange() &&
- this.currentRange_.start.node.state.focused)) {
- mode = ChromeVoxMode.COMPAT;
- } else {
- mode = ChromeVoxMode.CLASSIC;
- }
- }
+ localStorage['useNext'] = useNext;
+ if (useNext)
+ this.forceChromeVoxNextActive();
+ else
+ this.setCurrentRange(null);
+
+ var announce = Msgs.getMsg(useNext ?
+ 'switch_to_next' : 'switch_to_classic');
+ cvox.ChromeVox.tts.speak(
+ announce, cvox.QueueMode.FLUSH, {doNotInterrupt: true});
+ Notifications.onModeChange();
- this.setMode(mode);
+ // If the new mode is Classic, return false now so we don't announce
+ // anything more.
+ return useNext;
},
/**
@@ -335,29 +346,22 @@ Background.prototype = {
* @override
*/
setCurrentRange: function(newRange) {
- if (!newRange)
- return;
-
- // Is the range invalid?
- if (newRange.start.node.role === undefined ||
- newRange.end.node.role === undefined) {
- // Restore range to the focused location.
- chrome.automation.getFocus(function(f) {
- newRange = cursors.Range.fromNode(f);
- });
- }
-
- if (!this.inExcursion_)
+ if (!this.inExcursion_ && newRange)
this.savedRange_ = new cursors.Range(newRange.start, newRange.end);
this.currentRange_ = newRange;
+ var oldMode = this.mode_;
dmazzoni 2016/06/21 21:21:02 Could these 5 lines be refreshMode()? Then any ca
David Tseng 2016/06/21 22:41:32 I'd like to limit the number of methods exposed by
+ var newMode = this.getMode();
+ if (oldMode != newMode) {
+ this.onModeChanged_(newMode, oldMode);
+ this.mode_ = newMode;
+ }
if (this.currentRange_) {
var start = this.currentRange_.start.node;
start.makeVisible();
var root = start.root;
-
if (!root || root.role == RoleType.desktop)
return;
@@ -373,7 +377,7 @@ Background.prototype = {
/** Forces ChromeVox Next to be active for all tabs. */
forceChromeVoxNextActive: function() {
dmazzoni 2016/06/21 21:21:02 This doesn't actually force it active, it assumes
David Tseng 2016/06/21 22:41:32 Yup; removed and in-lined since there are no exter
- this.setMode(ChromeVoxMode.FORCE_NEXT);
+ this.onModeChanged_(ChromeVoxMode.FORCE_NEXT, ChromeVoxMode.CLASSIC);
},
/**
@@ -396,7 +400,7 @@ Background.prototype = {
if (!this.currentRange_)
return true;
- if (this.mode_ == ChromeVoxMode.CLASSIC && !opt_bypassModeCheck)
+ if (this.mode == ChromeVoxMode.CLASSIC && !opt_bypassModeCheck)
return true;
var current = this.currentRange_;
@@ -607,26 +611,8 @@ Background.prototype = {
}
break;
case 'toggleChromeVoxVersion':
- var newMode;
- if (this.mode_ == ChromeVoxMode.FORCE_NEXT) {
- var inWeb = current.isWebRange();
- newMode = inWeb ? ChromeVoxMode.CLASSIC : ChromeVoxMode.COMPAT;
- } else {
- newMode = ChromeVoxMode.FORCE_NEXT;
- }
- this.setMode(newMode, true);
-
- var isClassic =
- newMode == ChromeVoxMode.CLASSIC || newMode == ChromeVoxMode.COMPAT;
-
- // Leaving unlocalized as 'next' isn't an official name.
- cvox.ChromeVox.tts.speak(isClassic ?
- 'classic' : 'next', cvox.QueueMode.FLUSH, {doNotInterrupt: true});
-
- // If the new mode is Classic, return now so we don't announce
- // anything more.
- if (newMode == ChromeVoxMode.CLASSIC)
- return false;
+ if (!this.toggleNext())
+ return false;
break;
case 'toggleStickyMode':
cvox.ChromeVoxBackground.setPref('sticky',
@@ -787,7 +773,7 @@ Background.prototype = {
case 'reportIssue':
var url = Background.ISSUE_URL;
var description = {};
- description['Mode'] = this.mode_;
+ description['Mode'] = this.mode;
description['Version'] = chrome.app.getDetails().version;
description['Reproduction Steps'] = '%0a1.%0a2.%0a3.';
for (var key in description)
@@ -908,7 +894,7 @@ Background.prototype = {
if (cvox.ChromeVox.passThroughMode)
return false;
- if (this.mode_ != ChromeVoxMode.CLASSIC &&
+ if (this.mode != ChromeVoxMode.CLASSIC &&
!cvox.ChromeVoxKbHandler.basicKeyDownActionsListener(evt)) {
evt.preventDefault();
evt.stopPropagation();
@@ -951,7 +937,7 @@ Background.prototype = {
* @return {boolean} True if evt was processed.
*/
onBrailleKeyEvent: function(evt, content) {
- if (this.mode_ === ChromeVoxMode.CLASSIC)
+ if (this.mode === ChromeVoxMode.CLASSIC)
return false;
switch (evt.command) {
@@ -991,12 +977,24 @@ Background.prototype = {
* @private
*/
shouldEnableClassicForUrl_: function(url) {
- return this.mode_ != ChromeVoxMode.FORCE_NEXT &&
+ return this.mode != ChromeVoxMode.FORCE_NEXT &&
!this.isBlacklistedForClassic_(url) &&
!this.isWhitelistedForNext_(url);
},
/**
+ * Compat mode is on if any of the following are true:
+ * 1. a url is blacklisted for Classic.
+ * 2. the current range is not within web content.
+ * @param {string} url
+ */
+ isWhitelistedForCompat_: function(url) {
+ return this.isBlacklistedForClassic_(url) || (this.getCurrentRange() &&
+ !this.getCurrentRange().isWebRange() &&
+ this.getCurrentRange().start.node.state.focused);
+ },
+
+ /**
* @param {string} url
* @return {boolean}
* @private
@@ -1150,7 +1148,7 @@ Background.prototype = {
// If we're in classic mode, some gestures need to be handled by the
// content script. Other gestures are universal and will be handled in
// this function.
- if (this.mode_ == ChromeVoxMode.CLASSIC) {
+ if (this.mode == ChromeVoxMode.CLASSIC) {
if (this.handleClassicGesture_(gesture))
return;
}

Powered by Google App Engine
This is Rietveld 408576698