| 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 39a84175ea883f42b060d5cddbc4b93ca3fb11cc..1e0478a1402e83a50e0cd337adb022f241d6f595 100644
|
| --- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/background.js
|
| +++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/background.js
|
| @@ -17,6 +17,7 @@ goog.require('LiveRegions');
|
| goog.require('NextEarcons');
|
| goog.require('Output');
|
| goog.require('Output.EventType');
|
| +goog.require('PanelCommand');
|
| goog.require('constants');
|
| goog.require('cursors.Cursor');
|
| goog.require('cvox.BrailleKeyCommand');
|
| @@ -63,6 +64,12 @@ Background = function() {
|
| this.currentRange_ = null;
|
|
|
| /**
|
| + * @type {cursors.Range}
|
| + * @private
|
| + */
|
| + this.savedRange_ = null;
|
| +
|
| + /**
|
| * Which variant of ChromeVox is active.
|
| * @type {ChromeVoxMode}
|
| * @private
|
| @@ -194,6 +201,13 @@ Background.prototype = {
|
| cvox.ChromeVox.earcons.cancelEarcon(cvox.Earcon.PAGE_START_LOADING);
|
| }
|
|
|
| + if (mode === ChromeVoxMode.NEXT ||
|
| + mode === ChromeVoxMode.FORCE_NEXT) {
|
| + (new PanelCommand(PanelCommandType.ENABLE_MENUS)).send();
|
| + } else {
|
| + (new PanelCommand(PanelCommandType.DISABLE_MENUS)).send();
|
| + }
|
| +
|
| this.mode_ = mode;
|
| },
|
|
|
| @@ -235,6 +249,10 @@ Background.prototype = {
|
| if (!newRange)
|
| return;
|
|
|
| + var panelUrl = chrome.extension.getURL('cvox2/background/panel.html');
|
| + if (newRange.start.node.root.docUrl.indexOf(panelUrl) != 0)
|
| + this.savedRange_ = new cursors.Range(newRange.start, newRange.end);
|
| +
|
| this.currentRange_ = newRange;
|
|
|
| if (this.currentRange_)
|
| @@ -295,12 +313,12 @@ Background.prototype = {
|
| pred = AutomationPredicate.button;
|
| predErrorMsg = 'no_previous_button';
|
| break;
|
| - case 'nextCheckBox':
|
| + case 'nextCheckbox':
|
| dir = Dir.FORWARD;
|
| pred = AutomationPredicate.checkBox;
|
| predErrorMsg = 'no_next_checkbox';
|
| break;
|
| - case 'previousCheckBox':
|
| + case 'previousCheckbox':
|
| dir = Dir.BACKWARD;
|
| pred = AutomationPredicate.checkBox;
|
| predErrorMsg = 'no_previous_checkbox';
|
| @@ -376,14 +394,14 @@ Background.prototype = {
|
| predErrorMsg = 'no_previous_visited_link';
|
| break;
|
| case 'right':
|
| - case 'nextElement':
|
| + case 'nextObject':
|
| current = current.move(cursors.Unit.DOM_NODE, Dir.FORWARD);
|
| break;
|
| case 'left':
|
| - case 'previousElement':
|
| + case 'previousObject':
|
| current = current.move(cursors.Unit.DOM_NODE, Dir.BACKWARD);
|
| break;
|
| - case 'goToBeginning':
|
| + case 'jumpToTop':
|
| var node =
|
| AutomationUtil.findNodePost(current.start.node.root,
|
| Dir.FORWARD,
|
| @@ -391,7 +409,7 @@ Background.prototype = {
|
| if (node)
|
| current = cursors.Range.fromNode(node);
|
| break;
|
| - case 'goToEnd':
|
| + case 'jumpToBottom':
|
| var node =
|
| AutomationUtil.findNodePost(current.start.node.root,
|
| Dir.BACKWARD,
|
| @@ -400,7 +418,7 @@ Background.prototype = {
|
| current = cursors.Range.fromNode(node);
|
| break;
|
| case 'forceClickOnCurrentItem':
|
| - case 'doDefault':
|
| + case 'performDefaultAction':
|
| if (this.currentRange_) {
|
| var actionNode = this.currentRange_.start.node;
|
| if (actionNode.role == RoleType.inlineTextBox)
|
| @@ -410,7 +428,7 @@ Background.prototype = {
|
| // Skip all other processing; if focus changes, we should get an event
|
| // for that.
|
| return false;
|
| - case 'continuousRead':
|
| + case 'readFromHere':
|
| global.isReadingContinuously = true;
|
| var continueReading = function() {
|
| if (!global.isReadingContinuously || !this.currentRange_)
|
| @@ -442,7 +460,7 @@ Background.prototype = {
|
| .go();
|
|
|
| return false;
|
| - case 'showContextMenu':
|
| + case 'contextMenu':
|
| if (this.currentRange_) {
|
| var actionNode = this.currentRange_.start.node;
|
| if (actionNode.role == RoleType.inlineTextBox)
|
| @@ -497,6 +515,27 @@ Background.prototype = {
|
| cvox.ChromeVox.tts.speak(
|
| Msgs.getMsg('pass_through_key'), cvox.QueueMode.QUEUE);
|
| return true;
|
| + case 'openChromeVoxMenus':
|
| + (new PanelCommand(PanelCommandType.OPEN_MENUS)).send();
|
| + break;
|
| + case 'decreaseTtsRate':
|
| + this.increaseOrDecreaseSpeechProperty_(cvox.AbstractTts.RATE, false);
|
| + break;
|
| + case 'increaseTtsRate':
|
| + this.increaseOrDecreaseSpeechProperty_(cvox.AbstractTts.RATE, true);
|
| + break;
|
| + case 'decreaseTtsPitch':
|
| + this.increaseOrDecreaseSpeechProperty_(cvox.AbstractTts.PITCH, false);
|
| + break;
|
| + case 'increaseTtsPitch':
|
| + this.increaseOrDecreaseSpeechProperty_(cvox.AbstractTts.PITCH, true);
|
| + break;
|
| + case 'decreaseTtsVolume':
|
| + this.increaseOrDecreaseSpeechProperty_(cvox.AbstractTts.VOLUME, false);
|
| + break;
|
| + case 'increaseTtsVolume':
|
| + this.increaseOrDecreaseSpeechProperty_(cvox.AbstractTts.VOLUME, true);
|
| + break;
|
| default:
|
| return true;
|
| }
|
| @@ -516,27 +555,64 @@ Background.prototype = {
|
| }
|
| }
|
|
|
| - if (current) {
|
| - // TODO(dtseng): Figure out what it means to focus a range.
|
| - var actionNode = current.start.node;
|
| - if (actionNode.role == RoleType.inlineTextBox)
|
| - actionNode = actionNode.parent;
|
| + if (current)
|
| + this.navigateToRange_(current);
|
|
|
| - // Iframes, when focused, causes the child webArea to fire focus event.
|
| - // This can result in getting stuck when navigating backward.
|
| - if (actionNode.role != RoleType.iframe && !actionNode.state.focused)
|
| - actionNode.focus();
|
| -
|
| - var prevRange = this.currentRange_;
|
| - this.setCurrentRange(current);
|
| + return false;
|
| + },
|
|
|
| - new Output().withSpeechAndBraille(
|
| - this.currentRange_, prevRange, Output.EventType.NAVIGATE)
|
| - .withQueueMode(cvox.QueueMode.FLUSH)
|
| - .go();
|
| + /**
|
| + * Increase or decrease a speech property and make an announcement.
|
| + * @param {string} propertyName The name of the property to change.
|
| + * @param {boolean} increase If true, increases the property value by one
|
| + * step size, otherwise decreases.
|
| + */
|
| + increaseOrDecreaseSpeechProperty_: function(propertyName, increase) {
|
| + cvox.ChromeVox.tts.increaseOrDecreaseProperty(propertyName, increase);
|
| + var announcement;
|
| + var valueAsPercent = Math.round(
|
| + cvox.ChromeVox.tts.propertyToPercentage(propertyName) * 100);
|
| + switch (propertyName) {
|
| + case cvox.AbstractTts.RATE:
|
| + announcement = Msgs.getMsg('announce_rate', [valueAsPercent]);
|
| + break;
|
| + case cvox.AbstractTts.PITCH:
|
| + announcement = Msgs.getMsg('announce_pitch', [valueAsPercent]);
|
| + break;
|
| + case cvox.AbstractTts.VOLUME:
|
| + announcement = Msgs.getMsg('announce_volume', [valueAsPercent]);
|
| + break;
|
| }
|
| + if (announcement) {
|
| + cvox.ChromeVox.tts.speak(
|
| + announcement, cvox.QueueMode.FLUSH,
|
| + cvox.AbstractTts.PERSONALITY_ANNOTATION);
|
| + }
|
| + },
|
|
|
| - return false;
|
| + /**
|
| + * Navigate to the given range - it both sets the range and outputs it.
|
| + * @param {!cursors.Range} range The new range.
|
| + * @private
|
| + */
|
| + navigateToRange_: function(range) {
|
| + // TODO(dtseng): Figure out what it means to focus a range.
|
| + var actionNode = range.start.node;
|
| + if (actionNode.role == RoleType.inlineTextBox)
|
| + actionNode = actionNode.parent;
|
| +
|
| + // Iframes, when focused, causes the child webArea to fire focus event.
|
| + // This can result in getting stuck when navigating backward.
|
| + if (actionNode.role != RoleType.iframe && !actionNode.state.focused)
|
| + actionNode.focus();
|
| +
|
| + var prevRange = this.currentRange_;
|
| + this.setCurrentRange(range);
|
| +
|
| + new Output().withSpeechAndBraille(
|
| + range, prevRange, Output.EventType.NAVIGATE)
|
| + .withQueueMode(cvox.QueueMode.FLUSH)
|
| + .go();
|
| },
|
|
|
| /**
|
| @@ -597,10 +673,10 @@ Background.prototype = {
|
|
|
| switch (evt.command) {
|
| case cvox.BrailleKeyCommand.PAN_LEFT:
|
| - this.onGotCommand('previousElement');
|
| + this.onGotCommand('previousObject');
|
| break;
|
| case cvox.BrailleKeyCommand.PAN_RIGHT:
|
| - this.onGotCommand('nextElement');
|
| + this.onGotCommand('nextObject');
|
| break;
|
| case cvox.BrailleKeyCommand.LINE_UP:
|
| this.onGotCommand('previousLine');
|
| @@ -609,10 +685,10 @@ Background.prototype = {
|
| this.onGotCommand('nextLine');
|
| break;
|
| case cvox.BrailleKeyCommand.TOP:
|
| - this.onGotCommand('goToBeginning');
|
| + this.onGotCommand('jumpToTop');
|
| break;
|
| case cvox.BrailleKeyCommand.BOTTOM:
|
| - this.onGotCommand('goToEnd');
|
| + this.onGotCommand('jumpToBottom');
|
| break;
|
| case cvox.BrailleKeyCommand.ROUTING:
|
| this.brailleRoutingCommand_(
|
| @@ -723,7 +799,24 @@ Background.prototype = {
|
| }
|
| break;
|
| }
|
| - }
|
| + },
|
| +
|
| + /**
|
| + * Restore the range to the last range that was *not* in the ChromeVox
|
| + * panel. This is used when the ChromeVox Panel closes.
|
| + */
|
| + restoreCurrentRange: function() {
|
| + if (this.savedRange_) {
|
| + var containingWebView = this.savedRange_.start.node;
|
| + while (containingWebView && containingWebView.role != RoleType.webView)
|
| + containingWebView = containingWebView.parent;
|
| + if (containingWebView)
|
| + containingWebView.focus();
|
| +
|
| + this.navigateToRange_(this.savedRange_);
|
| + this.savedRange_ = null;
|
| + }
|
| + },
|
| };
|
|
|
| /**
|
|
|