summaryrefslogtreecommitdiffstats
path: root/chrome/browser/resources/chromeos/chromevox/cvox2/background/background.js
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/resources/chromeos/chromevox/cvox2/background/background.js')
-rw-r--r--chrome/browser/resources/chromeos/chromevox/cvox2/background/background.js248
1 files changed, 103 insertions, 145 deletions
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/background.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/background.js
index 523e200..b7ba66a 100644
--- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/background.js
+++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/background.js
@@ -8,11 +8,12 @@
*/
goog.provide('Background');
-goog.provide('ChromeVoxMode');
goog.provide('global');
goog.require('AutomationPredicate');
goog.require('AutomationUtil');
+goog.require('ChromeVoxState');
+goog.require('LiveRegions');
goog.require('NextEarcons');
goog.require('Output');
goog.require('Output.EventType');
@@ -31,21 +32,13 @@ var EventType = chrome.automation.EventType;
var RoleType = chrome.automation.RoleType;
/**
- * All possible modes ChromeVox can run.
- * @enum {string}
- */
-ChromeVoxMode = {
- CLASSIC: 'classic',
- COMPAT: 'compat',
- NEXT: 'next',
- FORCE_NEXT: 'force_next'
-};
-
-/**
* ChromeVox2 background page.
* @constructor
+ * @extends {ChromeVoxState}
*/
Background = function() {
+ ChromeVoxState.call(this);
+
/**
* A list of site substring patterns to use with ChromeVox next. Keep these
* strings relatively specific.
@@ -127,35 +120,115 @@ Background = function() {
// Classic keymap.
cvox.ChromeVoxKbHandler.handlerKeyMap = cvox.KeyMap.fromDefaults();
- chrome.automation.addTreeChangeObserver(this.onTreeChange);
+ // Live region handler.
+ this.liveRegions_ = new LiveRegions(this);
};
Background.prototype = {
- /** Forces ChromeVox Next to be active for all tabs. */
- forceChromeVoxNextActive: function() {
- this.setChromeVoxMode(ChromeVoxMode.FORCE_NEXT);
- },
+ __proto__: ChromeVoxState.prototype,
- /** @type {ChromeVoxMode} */
- get mode() {
+ /**
+ * @override
+ */
+ getMode: function() {
return this.mode_;
},
- /** @type {cursors.Range} */
- get currentRange() {
+ /**
+ * @override
+ */
+ setMode: function(mode, opt_injectClassic) {
+ // 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)
+ cvox.ChromeVoxKbHandler.handlerKeyMap = cvox.KeyMap.fromDefaults();
+ else
+ cvox.ChromeVoxKbHandler.handlerKeyMap = cvox.KeyMap.fromNext();
+
+ if (mode == ChromeVoxMode.CLASSIC) {
+ if (chrome.commands &&
+ chrome.commands.onCommand.hasListener(this.onGotCommand))
+ chrome.commands.onCommand.removeListener(this.onGotCommand);
+ } else {
+ if (chrome.commands &&
+ !chrome.commands.onCommand.hasListener(this.onGotCommand))
+ chrome.commands.onCommand.addListener(this.onGotCommand);
+ }
+
+ chrome.tabs.query({active: true}, function(tabs) {
+ if (mode === 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)
+ cvox.ChromeVox.injectChromeVoxIntoTabs(tabs);
+ } else {
+ // When in compat mode, if the focus is within the desktop tree proper,
+ // then do not disable content scripts.
+ if (this.currentRange_ &&
+ this.currentRange_.start.node.root.role == RoleType.desktop)
+ return;
+
+ this.disableClassicChromeVox_();
+ }
+ }.bind(this));
+
+ // 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) {
+ cvox.ChromeVox.earcons.cancelEarcon(cvox.Earcon.PAGE_START_LOADING);
+ }
+
+ this.mode_ = mode;
+ },
+
+ /**
+ * @override
+ */
+ refreshMode: function(url) {
+ var mode = this.mode_;
+ if (mode != ChromeVoxMode.FORCE_NEXT) {
+ if (this.isWhitelistedForNext_(url))
+ mode = ChromeVoxMode.NEXT;
+ else if (this.isBlacklistedForClassic_(url))
+ mode = ChromeVoxMode.COMPAT;
+ else
+ mode = ChromeVoxMode.CLASSIC;
+ }
+
+ this.setMode(mode);
+ },
+
+ /**
+ * @override
+ */
+ getCurrentRange: function() {
return this.currentRange_;
},
- set currentRange(value) {
- if (!value)
+ /**
+ * @override
+ */
+ setCurrentRange: function(newRange) {
+ if (!newRange)
return;
- this.currentRange_ = value;
+ this.currentRange_ = newRange;
if (this.currentRange_)
this.currentRange_.start.node.makeVisible();
},
+ /** Forces ChromeVox Next to be active for all tabs. */
+ forceChromeVoxNextActive: function() {
+ this.setMode(ChromeVoxMode.FORCE_NEXT);
+ },
+
/**
* Handles ChromeVox Next commands.
* @param {string} command
@@ -331,8 +404,8 @@ Background.prototype = {
.onSpeechEnd(function() { continueReading(prevRange); })
.go();
prevRange = this.currentRange_;
- this.currentRange =
- this.currentRange.move(cursors.Unit.NODE, Dir.FORWARD);
+ this.setCurrentRange(
+ this.currentRange_.move(cursors.Unit.NODE, Dir.FORWARD));
if (!this.currentRange_ || this.currentRange_.equals(prevRange))
global.isReadingContinuously = false;
@@ -372,7 +445,7 @@ Background.prototype = {
} else {
newMode = ChromeVoxMode.FORCE_NEXT;
}
- this.setChromeVoxMode(newMode, true);
+ this.setMode(newMode, true);
var isClassic =
newMode == ChromeVoxMode.CLASSIC || newMode == ChromeVoxMode.COMPAT;
@@ -408,7 +481,7 @@ Background.prototype = {
actionNode.focus();
var prevRange = this.currentRange_;
- this.currentRange = current;
+ this.setCurrentRange(current);
new Output().withSpeechAndBraille(
this.currentRange_, prevRange, Output.EventType.NAVIGATE)
@@ -429,6 +502,8 @@ Background.prototype = {
evt.preventDefault();
evt.stopPropagation();
}
+
+ Output.flushNextSpeechUtterance();
},
/**
@@ -481,67 +556,6 @@ Background.prototype = {
},
/**
- * Refreshes the current mode based on a url.
- * @param {string} url
- */
- refreshMode: function(url) {
- var mode = this.mode_;
- if (mode != ChromeVoxMode.FORCE_NEXT) {
- if (this.isWhitelistedForNext_(url))
- mode = ChromeVoxMode.NEXT;
- else if (this.isBlacklistedForClassic_(url))
- mode = ChromeVoxMode.COMPAT;
- else
- mode = ChromeVoxMode.CLASSIC;
- }
-
- this.setChromeVoxMode(mode);
- },
-
- /**
- * Called when the automation tree is changed.
- * @param {chrome.automation.TreeChange} treeChange
- */
- onTreeChange: function(treeChange) {
- if (this.mode_ === ChromeVoxMode.CLASSIC || !cvox.ChromeVox.isActive)
- return;
-
- var node = treeChange.target;
- if (!node.containerLiveStatus)
- return;
-
- if (node.containerLiveRelevant.indexOf('additions') >= 0 &&
- treeChange.type == 'nodeCreated')
- this.outputLiveRegionChange_(node, null);
- if (node.containerLiveRelevant.indexOf('text') >= 0 &&
- treeChange.type == 'nodeChanged')
- this.outputLiveRegionChange_(node, null);
- if (node.containerLiveRelevant.indexOf('removals') >= 0 &&
- treeChange.type == 'nodeRemoved')
- this.outputLiveRegionChange_(node, '@live_regions_removed');
- },
-
- /**
- * Given a node that needs to be spoken as part of a live region
- * change and an additional optional format string, output the
- * live region description.
- * @param {!chrome.automation.AutomationNode} node The changed node.
- * @param {?string} opt_prependFormatStr If set, a format string for
- * cvox2.Output to prepend to the output.
- * @private
- */
- outputLiveRegionChange_: function(node, opt_prependFormatStr) {
- var range = cursors.Range.fromNode(node);
- var output = new Output();
- if (opt_prependFormatStr) {
- output.format(opt_prependFormatStr);
- }
- output.withSpeech(range, null, Output.EventType.NAVIGATE);
- output.withSpeechCategory(cvox.TtsCategory.LIVE);
- output.go();
- },
-
- /**
* Returns true if the url should have Classic running.
* @return {boolean}
* @private
@@ -583,62 +597,6 @@ Background.prototype = {
},
/**
- * Sets the current ChromeVox mode.
- * @param {ChromeVoxMode} mode
- * @param {boolean=} opt_injectClassic Injects ChromeVox classic into tabs;
- * defaults to false.
- */
- setChromeVoxMode: function(mode, opt_injectClassic) {
- // 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)
- cvox.ChromeVoxKbHandler.handlerKeyMap = cvox.KeyMap.fromDefaults();
- else
- cvox.ChromeVoxKbHandler.handlerKeyMap = cvox.KeyMap.fromNext();
-
- if (mode == ChromeVoxMode.CLASSIC) {
- if (chrome.commands &&
- chrome.commands.onCommand.hasListener(this.onGotCommand))
- chrome.commands.onCommand.removeListener(this.onGotCommand);
- } else {
- if (chrome.commands &&
- !chrome.commands.onCommand.hasListener(this.onGotCommand))
- chrome.commands.onCommand.addListener(this.onGotCommand);
- }
-
- chrome.tabs.query({active: true}, function(tabs) {
- if (mode === 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)
- cvox.ChromeVox.injectChromeVoxIntoTabs(tabs);
- } else {
- // When in compat mode, if the focus is within the desktop tree proper,
- // then do not disable content scripts.
- if (this.currentRange_ &&
- this.currentRange_.start.node.root.role == RoleType.desktop)
- return;
-
- this.disableClassicChromeVox_();
- }
- }.bind(this));
-
- // 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) {
- cvox.ChromeVox.earcons.cancelEarcon(cvox.Earcon.PAGE_START_LOADING);
- }
-
- this.mode_ = mode;
- },
-
- /**
* @param {!Spannable} text
* @param {number} position
* @private