Commit c0e53b73 authored by David Tseng's avatar David Tseng Committed by Commit Bot

Reland: Remove |mode| from ChromeVox

Debug generates slightly different output than release.

TBR=dtseng@chromium.org

Original description:
ChromeVox Classic is no longer available to users.
This allows us to remove some complexity surrounding the idea of the various modes for ChromeVox (classic, next, etc).

This change mostly is meant to be cleanup, but it also addresses some bugs. Namely, we unintentionally relied upon onModeChanged to trigger specific behaviors such as installing command handlers. This made sense when mode changes had to be supported. However, with this in a limbo state now that there is no classic mode, we can no longer invoke commands with an empty desktop.

Original change:
https://chromium-review.googlesource.com/c/chromium/src/+/825169

Bug: 
Change-Id: Ibcfe282ceacac766ca47edecaa3302d59be8fcd5
Cq-Include-Trybots: master.tryserver.chromium.linux:closure_compilation
Reviewed-on: https://chromium-review.googlesource.com/829976Reviewed-by: default avatarDavid Tseng <dtseng@chromium.org>
Commit-Queue: David Tseng <dtseng@chromium.org>
Cr-Commit-Position: refs/heads/master@{#524496}
parent 2126b752
......@@ -526,8 +526,6 @@ IN_PROC_BROWSER_TEST_P(SpokenFeedbackTest, MAYBE_ChromeVoxShiftSearch) {
if (utterance == "Click me")
break;
}
speech_monitor_.GetNextUtterance();
EXPECT_EQ("Button", speech_monitor_.GetNextUtterance());
// Press Search+/ to enter ChromeVox's "find in page".
SendKeyPressWithSearch(ui::VKEY_OEM_2);
......
......@@ -148,7 +148,6 @@ chromevox_modules = [
"cvox2/background/panel_menu.js",
"cvox2/background/panel_menu_item.js",
"cvox2/background/recovery_strategy.js",
"cvox2/background/tabs_automation_handler.js",
"cvox2/background/tree_walker.js",
"cvox2/background/tutorial.js",
"cvox2/injected/keyboard_handler.js",
......
......@@ -9,7 +9,6 @@
goog.provide('cvox.TabsApiHandler');
goog.require('TabsAutomationHandler');
goog.require('cvox.AbstractEarcons');
goog.require('cvox.AbstractTts');
goog.require('cvox.BrailleInterface');
......@@ -73,9 +72,6 @@ cvox.TabsApiHandler.prototype = {
cvox.NavBraille.fromText(this.msg_('chrome_tab_created')));
}
cvox.ChromeVox.earcons.playEarcon(cvox.Earcon.OBJECT_OPEN);
if (tab) {
this.refreshAutomationHandler_(tab.id);
}
},
/**
......@@ -115,7 +111,6 @@ cvox.TabsApiHandler.prototype = {
this.msg_('chrome_tab_selected', [title])));
}
cvox.ChromeVox.earcons.playEarcon(cvox.Earcon.OBJECT_SELECT);
this.refreshAutomationHandler_(tab.id);
}.bind(this));
},
......@@ -161,7 +156,6 @@ cvox.TabsApiHandler.prototype = {
cvox.ChromeVox.earcons.playEarcon(cvox.Earcon.PAGE_FINISH_LOADING);
this.cancelPageLoadTimer_();
}
this.refreshAutomationHandler_(tabId);
}.bind(this));
},
......@@ -193,29 +187,10 @@ cvox.TabsApiHandler.prototype = {
cvox.NavBraille.fromText(this.msg_(msgId, [title])));
}
cvox.ChromeVox.earcons.playEarcon(cvox.Earcon.OBJECT_SELECT);
this.refreshAutomationHandler_(tab.id);
}.bind(this));
}.bind(this));
},
/**
* Installs a new automation handler for the given tab.
* @param {number} tabId
* @private
*/
refreshAutomationHandler_: function(tabId) {
if (!cvox.ChromeVox.isMac ||
ChromeVoxState.instance.mode == ChromeVoxMode.CLASSIC)
return;
chrome.automation.getTree(tabId, function(node) {
if (this.handler_)
this.handler_.removeAllListeners();
this.handler_ = new TabsAutomationHandler(node);
}.bind(this));
},
/**
* The chrome.tabs API doesn't always fire an onUpdated event when a
* page finishes loading, so we poll it.
......
......@@ -15,6 +15,7 @@ goog.require('BackgroundKeyboardHandler');
goog.require('BrailleCommandHandler');
goog.require('ChromeVoxState');
goog.require('CommandHandler');
goog.require('DesktopAutomationHandler');
goog.require('FindHandler');
goog.require('LiveRegions');
goog.require('MediaAutomationHandler');
......@@ -28,7 +29,6 @@ goog.require('cursors.Cursor');
goog.require('cvox.BrailleKeyCommand');
goog.require('cvox.ChromeVoxBackground');
goog.require('cvox.ChromeVoxEditableTextBase');
goog.require('cvox.ClassicEarcons');
goog.require('cvox.ExtensionBridge');
goog.require('cvox.NavBraille');
......@@ -55,22 +55,6 @@ Background = function() {
*/
this.whitelist_ = ['chromevox_next_test'];
/**
* A list of site substring patterns to blacklist ChromeVox Classic,
* putting ChromeVox into classic Compat mode.
* @type {!Set<string>}
* @private
*/
this.classicBlacklist_ = new Set();
/**
* Regular expression for blacklisting classic.
* @type {RegExp}
* @private
*/
this.classicBlacklistRegExp_ = Background.globsToRegExp_(
chrome.runtime.getManifest()['content_scripts'][0]['exclude_globs']);
/**
* @type {cursors.Range}
* @private
......@@ -83,32 +67,20 @@ Background = function() {
this[func] = this[func].bind(this);
}
/** @type {!cvox.AbstractEarcons} @private */
this.classicEarcons_ = cvox.ChromeVox.earcons || new cvox.ClassicEarcons();
/** @type {!cvox.AbstractEarcons} @private */
this.nextEarcons_ = new NextEarcons();
// Turn cvox.ChromeVox.earcons into a getter that returns either the
// Next earcons or the Classic earcons depending on the current mode.
// Read-only earcons.
Object.defineProperty(cvox.ChromeVox, 'earcons', {
get: (function() {
if (this.mode === ChromeVoxMode.FORCE_NEXT ||
this.mode === ChromeVoxMode.NEXT) {
return this.nextEarcons_;
} else {
return this.classicEarcons_;
}
return this.nextEarcons_;
}).bind(this)
});
if (cvox.ChromeVox.isChromeOS) {
Object.defineProperty(cvox.ChromeVox, 'modKeyStr', {
get: function() {
return (this.mode == ChromeVoxMode.CLASSIC ||
this.mode == ChromeVoxMode.CLASSIC_COMPAT) ?
'Search+Shift' :
'Search';
return 'Search';
}.bind(this)
});
......@@ -149,13 +121,6 @@ Background = function() {
/** @type {!LiveRegions} @private */
this.liveRegions_ = new LiveRegions(this);
/**
* Stores the mode as computed the last time a current range was set.
* @type {?ChromeVoxMode}
* @private
*/
this.mode_ = null;
chrome.accessibilityPrivate.onAccessibilityGesture.addListener(
this.onAccessibilityGesture_);
......@@ -179,37 +144,19 @@ Background = function() {
this.chromeChannel_ = desktop.chromeChannel;
}.bind(this));
// Record a metric with the mode we're in on startup.
var useNext = localStorage['useClassic'] != 'true';
chrome.metricsPrivate.recordBoolean(
'Accessibility.CrosChromeVoxNext', useNext);
CommandHandler.init();
FindHandler.init();
Notifications.onStartup();
};
/**
* Map from gesture names (AXGesture defined in ui/accessibility/ax_enums.idl)
* to commands when in Classic mode.
* @type {Object<string, string>}
* @const
*/
Background.GESTURE_CLASSIC_COMMAND_MAP = {
'click': 'forceClickOnCurrentItem',
'swipeUp1': 'backward',
'swipeDown1': 'forward',
'swipeLeft1': 'left',
'swipeRight1': 'right',
'swipeUp2': 'jumpToTop',
'swipeDown2': 'readFromHere',
};
/**
* Map from gesture names (AXGesture defined in ui/accessibility/ax_enums.idl)
* to commands when in Classic mode.
* to commands.
* @type {Object<string, string>}
* @const
*/
Background.GESTURE_NEXT_COMMAND_MAP = {
Background.GESTURE_COMMAND_MAP = {
'click': 'forceClickOnCurrentItem',
'swipeUp1': 'previousLine',
'swipeDown1': 'nextLine',
......@@ -231,110 +178,6 @@ Background.prototype = {
return this.focusRecoveryMap_;
},
/**
* @override
*/
getMode: function() {
var useNext = localStorage['useClassic'] !== 'true';
var target;
if (!this.getCurrentRange()) {
chrome.automation.getFocus(function(focus) {
target = focus;
});
} else {
target = this.getCurrentRange().start.node;
}
if (!target)
return useNext ? ChromeVoxMode.FORCE_NEXT : ChromeVoxMode.CLASSIC;
// Closure complains, but clearly, |target| is not null.
var topLevelRoot =
AutomationUtil.getTopLevelRoot(/** @type {!AutomationNode} */ (target));
if (!topLevelRoot)
return useNext ? ChromeVoxMode.FORCE_NEXT : ChromeVoxMode.CLASSIC_COMPAT;
var docUrl = topLevelRoot.docUrl || '';
var nextSite = this.isWhitelistedForNext_(docUrl);
var classicCompat = this.isWhitelistedForClassicCompat_(docUrl);
if (classicCompat && !useNext)
return ChromeVoxMode.CLASSIC_COMPAT;
else if (nextSite)
return ChromeVoxMode.NEXT;
else if (!useNext)
return ChromeVoxMode.CLASSIC;
else
return ChromeVoxMode.FORCE_NEXT;
},
/**
* Handles a mode change.
* @param {ChromeVoxMode} newMode
* @param {?ChromeVoxMode} oldMode Can be null at startup when no range was
* previously set.
* @private
*/
onModeChanged_: function(newMode, oldMode) {
this.keyboardHandler_.onModeChanged(newMode, oldMode);
CommandHandler.onModeChanged(newMode, oldMode);
FindHandler.onModeChanged(newMode, oldMode);
// The below logic handles transition between the classic engine
// (content script) and next engine (no content script) as well as
// misc states that are not handled above.
// Classic modes do not use the new focus highlight.
if (newMode == ChromeVoxMode.CLASSIC)
chrome.accessibilityPrivate.setFocusRing([]);
// Switch on/off content scripts.
// note that |this.currentRange_| can *change* because the request is
// async. Save it to ensure we're looking at the currentRange at this moment
// in time.
var cur = this.currentRange_;
chrome.tabs.query({active: true, lastFocusedWindow: true}, function(tabs) {
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 (oldMode == ChromeVoxMode.FORCE_NEXT) {
cvox.ChromeVox.injectChromeVoxIntoTabs(tabs);
}
} else if (newMode === ChromeVoxMode.FORCE_NEXT) {
this.disableClassicChromeVox_();
} else {
// If we're focused in the desktop tree, do nothing.
if (cur && !cur.isWebRange())
return;
// If we're entering classic compat mode or next mode for just one tab,
// disable Classic for that tab only.
this.disableClassicChromeVox_(tabs);
}
}.bind(this));
// Switching into either compat or classic.
if (oldMode === ChromeVoxMode.NEXT ||
oldMode === ChromeVoxMode.FORCE_NEXT) {
// Make sure we cancel the progress loading sound just in case.
cvox.ChromeVox.earcons.cancelEarcon(cvox.Earcon.PAGE_START_LOADING);
(new PanelCommand(PanelCommandType.DISABLE_MENUS)).send();
}
// Switching out of next, force next, or uninitialized (on startup).
if (newMode === ChromeVoxMode.NEXT ||
newMode === ChromeVoxMode.FORCE_NEXT) {
(new PanelCommand(PanelCommandType.ENABLE_MENUS)).send();
if (cvox.TabsApiHandler)
cvox.TabsApiHandler.shouldOutputSpeechAndBraille = false;
} else {
// |newMode| is either classic or compat.
if (cvox.TabsApiHandler)
cvox.TabsApiHandler.shouldOutputSpeechAndBraille = true;
}
},
/**
* @override
*/
......@@ -359,12 +202,6 @@ Background.prototype = {
ChromeVoxState.observers.forEach(function(observer) {
observer.onCurrentRangeChanged(newRange);
});
var oldMode = this.mode_;
var newMode = this.getMode();
if (oldMode != newMode) {
this.onModeChanged_(newMode, oldMode);
this.mode_ = newMode;
}
if (this.currentRange_) {
var start = this.currentRange_.start.node;
......@@ -481,9 +318,6 @@ Background.prototype = {
* @return {boolean} True if evt was processed.
*/
onBrailleKeyEvent: function(evt, content) {
if (this.mode === ChromeVoxMode.CLASSIC)
return false;
switch (evt.command) {
case cvox.BrailleKeyCommand.PAN_LEFT:
CommandHandler.onCommand('previousObject');
......@@ -523,73 +357,6 @@ Background.prototype = {
return true;
},
/**
* Returns true if the url should have Classic running.
* @return {boolean}
* @private
*/
shouldEnableClassicForUrl_: function(url) {
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
* @return {boolean}
*/
isWhitelistedForClassicCompat_: function(url) {
return (this.isBlacklistedForClassic_(url) ||
(this.getCurrentRange() && !this.getCurrentRange().isWebRange() &&
this.getCurrentRange().start.node.state[StateType.FOCUSED])) ||
false;
},
/**
* @param {string} url
* @return {boolean}
* @private
*/
isBlacklistedForClassic_: function(url) {
if (this.classicBlacklistRegExp_.test(url))
return true;
url = url.substring(0, url.indexOf('#')) || url;
return this.classicBlacklist_.has(url);
},
/**
* @param {string} url
* @return {boolean} Whether the given |url| is whitelisted.
* @private
*/
isWhitelistedForNext_: function(url) {
return this.whitelist_.some(function(item) {
return url.indexOf(item) != -1;
});
},
/**
* Disables classic ChromeVox in current web content.
* @param {Array<Tab>=} opt_tabs The tabs where ChromeVox scripts should be
* disabled. If null, will disable ChromeVox everywhere.
*/
disableClassicChromeVox_: function(opt_tabs) {
var disableChromeVoxCommand = {
message: 'SYSTEM_COMMAND',
command: 'killChromeVox'
};
if (opt_tabs) {
for (var i = 0, tab; tab = opt_tabs[i]; i++)
chrome.tabs.sendMessage(tab.id, disableChromeVoxCommand);
} else {
// Send to all ChromeVox clients.
cvox.ExtensionBridge.send(disableChromeVoxCommand);
}
},
/**
* @param {!Spannable} text
* @param {number} position
......@@ -667,14 +434,9 @@ Background.prototype = {
case 'next':
if (action == 'getIsClassicEnabled') {
var url = msg['url'];
var isClassicEnabled = this.shouldEnableClassicForUrl_(url);
var isClassicEnabled = false;
port.postMessage(
{target: 'next', isClassicEnabled: isClassicEnabled});
} else if (action == 'enableClassicCompatForUrl') {
var url = msg['url'];
this.classicBlacklist_.add(url);
if (this.currentRange_ && this.currentRange_.start.node)
this.setCurrentRange(this.currentRange_);
} else if (action == 'onCommand') {
CommandHandler.onCommand(msg['command']);
} else if (action == 'flushNextUtterance') {
......@@ -703,37 +465,11 @@ Background.prototype = {
* @private
*/
onAccessibilityGesture_: function(gesture) {
// 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.handleClassicGesture_(gesture))
return;
}
var command = Background.GESTURE_NEXT_COMMAND_MAP[gesture];
var command = Background.GESTURE_COMMAND_MAP[gesture];
if (command)
CommandHandler.onCommand(command);
},
/**
* Handles accessibility gestures from the touch screen when in CLASSIC
* mode, by forwarding a command to the content script.
* @param {string} gesture The gesture to handle, based on the AXGesture enum
* defined in ui/accessibility/ax_enums.idl
* @return {boolean} True if this gesture was handled.
* @private
*/
handleClassicGesture_: function(gesture) {
var command = Background.GESTURE_CLASSIC_COMMAND_MAP[gesture];
if (!command)
return false;
var msg = {'message': 'USER_COMMAND', 'command': command};
cvox.ExtensionBridge.send(msg);
return true;
},
/**
* Detects various clipboard events and provides spoken output.
*
......
......@@ -25,8 +25,6 @@ BackgroundTest.prototype = {
window.RoleType = chrome.automation.RoleType;
window.doCmd = this.doCmd;
// Reset notifications so only explicit mode changes can cause them to trigger.
Notifications.reset();
this.forceContextualLastOutput();
},
......@@ -514,78 +512,6 @@ TEST_F('BackgroundTest', 'DISABLED_ActiveOrInactive', function() {
});
});
TEST_F('BackgroundTest', 'ModeSwitching', function() {
this.runWithLoadedTree('<button></button>', function(root) {
var fakeDesktop = {};
fakeDesktop.role = 'desktop';
fakeDesktop.root = fakeDesktop;
var fakeWebRoot = {};
fakeWebRoot.root = fakeWebRoot;
fakeWebRoot.parent = fakeDesktop;
fakeWebRoot.role = RoleType.ROOT_WEB_AREA;
fakeWebRoot.makeVisible = function() {};
fakeWebRoot.unclippedLocation = {left: 1, top: 1, width: 1, height: 1};
var fakeSubRoot = {};
fakeSubRoot.root = fakeSubRoot;
fakeSubRoot.parent = fakeWebRoot;
fakeSubRoot.role = RoleType.ROOT_WEB_AREA;
fakeSubRoot.makeVisible = function() {};
fakeSubRoot.unclippedLocation = {left: 1, top: 1, width: 1, height: 1};
var bk = ChromeVoxState.instance;
// Tests default to force next mode.
assertEquals('force_next', bk.mode);
// Force next mode stays set regardless of where the range lands.
fakeWebRoot.docUrl = 'http://google.com';
bk.setCurrentRange(cursors.Range.fromNode(fakeWebRoot));
assertEquals('force_next', bk.mode);
// Empty urls occur before document load or when root is desktop.
fakeWebRoot.docUrl = '';
bk.setCurrentRange(cursors.Range.fromNode(fakeWebRoot));
assertEquals('force_next', bk.mode);
// Verify force next -> classic compat switching.
localStorage['useClassic'] = true;
fakeWebRoot.docUrl = 'chrome://foobar';
bk.setCurrentRange(cursors.Range.fromNode(fakeWebRoot));
assertEquals('classic_compat', bk.mode);
// Classic compat -> classic.
fakeWebRoot.docUrl = 'http://google.com';
bk.setCurrentRange(cursors.Range.fromNode(fakeWebRoot));
assertEquals('classic', bk.mode);
// Ensure we switch to classic compat if our current range has focused
// state set and is not in web content.
assertTrue(root.parent.state.focused);
bk.setCurrentRange(cursors.Range.fromNode(root.parent));
assertEquals('classic_compat', bk.mode);
// And back to classic.
bk.setCurrentRange(cursors.Range.fromNode(root));
assertEquals('classic', bk.mode);
// Now, verify mode switching uses the top level root.
fakeWebRoot.docUrl = 'http://google.com/#chromevox_next_test';
fakeSubRoot.docUrl = 'http://chromevox.com';
bk.setCurrentRange(cursors.Range.fromNode(fakeWebRoot));
assertEquals('next', bk.mode);
// Next compat switching.
localStorage['useClassic'] = false;
fakeWebRoot.docUrl = 'http://docs.google.com/document/#123123';
bk.setCurrentRange(cursors.Range.fromNode(fakeWebRoot));
assertEquals('force_next', bk.mode);
// And, back to force next.
fakeWebRoot.docUrl = 'http://docs.google.com/form/123';
bk.setCurrentRange(cursors.Range.fromNode(fakeWebRoot));
assertEquals('force_next', bk.mode);
}.bind(this));
});
TEST_F('BackgroundTest', 'ShouldNotFocusIframe', function() {
this.runWithLoadedTree( function() {/*!
<iframe tabindex=0 src="data:text/html,<p>Inside</p>"></iframe>
......
......@@ -8,24 +8,12 @@
* object and to facilitate mocking for tests.
*/
goog.provide('ChromeVoxMode');
goog.provide('ChromeVoxState');
goog.provide('ChromeVoxStateObserver');
goog.require('cursors.Cursor');
goog.require('cursors.Range');
/**
* All possible modes ChromeVox can run.
* @enum {string}
*/
ChromeVoxMode = {
CLASSIC: 'classic',
CLASSIC_COMPAT: 'classic_compat',
NEXT: 'next',
FORCE_NEXT: 'force_next'
};
/**
* An interface implemented by objects that want to observe ChromeVox state
* changes.
......@@ -67,19 +55,6 @@ ChromeVoxState.backgroundTts;
ChromeVoxState.isReadingContinuously;
ChromeVoxState.prototype = {
/** @type {ChromeVoxMode} */
get mode() {
return this.getMode();
},
/**
* @return {ChromeVoxMode} The current mode.
* @protected
*/
getMode: function() {
return ChromeVoxMode.NEXT;
},
/** @type {cursors.Range} */
get currentRange() {
return this.getCurrentRange();
......
......@@ -12,6 +12,7 @@ goog.require('ChromeVoxState');
goog.require('CustomAutomationEvent');
goog.require('Output');
goog.require('cvox.ChromeVoxBackground');
goog.require('cvox.ChromeVoxKbHandler');
goog.scope(function() {
var AutomationEvent = chrome.automation.AutomationEvent;
......@@ -39,7 +40,7 @@ CommandHandler.onCommand = function(command) {
ChromeVoxState.instance.setCurrentRange(null);
});
// These commands don't require a current range and work in all modes.
// These commands don't require a current range.
switch (command) {
case 'speakTimeAndDate':
chrome.automation.getDesktop(function(d) {
......@@ -170,7 +171,6 @@ CommandHandler.onCommand = function(command) {
'description=';
var description = {};
description['Mode'] = ChromeVoxState.instance.mode;
description['Version'] = chrome.app.getDetails().version;
description['Reproduction Steps'] = '%0a1.%0a2.%0a3.';
for (var key in description)
......@@ -237,10 +237,6 @@ CommandHandler.onCommand = function(command) {
if (!ChromeVoxState.instance.currentRange_)
return true;
// Next/classic compat commands hereafter.
if (ChromeVoxState.instance.mode == ChromeVoxMode.CLASSIC)
return true;
var current = ChromeVoxState.instance.currentRange_;
var dir = Dir.FORWARD;
var pred = null;
......@@ -812,24 +808,6 @@ CommandHandler.onCommand = function(command) {
return false;
};
/**
* React to mode changes.
* @param {ChromeVoxMode} newMode
* @param {ChromeVoxMode?} oldMode
*/
CommandHandler.onModeChanged = function(newMode, oldMode) {
// Previously uninitialized.
if (!oldMode)
cvox.ChromeVoxKbHandler.commandHandler = CommandHandler.onCommand;
var hasListener =
chrome.commands.onCommand.hasListener(CommandHandler.onCommand);
if (newMode == ChromeVoxMode.CLASSIC && hasListener)
chrome.commands.onCommand.removeListener(CommandHandler.onCommand);
else if (newMode == ChromeVoxMode.CLASSIC && !hasListener)
chrome.commands.onCommand.addListener(CommandHandler.onCommand);
};
/**
* Increase or decrease a speech property and make an announcement.
* @param {string} propertyName The name of the property to change.
......@@ -927,9 +905,9 @@ CommandHandler.viewGraphicAsBraille_ = function(current) {
/**
* Performs global initialization.
* @private
*/
CommandHandler.init_ = function() {
CommandHandler.init = function() {
cvox.ChromeVoxKbHandler.commandHandler = CommandHandler.onCommand;
var firstRunId = 'jdgcneonijmofocbhmijhacgchbihela';
chrome.runtime.onMessageExternal.addListener(function(
request, sender, sendResponse) {
......@@ -955,6 +933,4 @@ CommandHandler.init_ = function() {
});
};
CommandHandler.init_();
}); // goog.scope
......@@ -81,9 +81,6 @@ DesktopAutomationHandler = function(node) {
AutomationObjectConstructorInstaller.init(node, function() {
chrome.automation.getFocus(
(function(focus) {
if (ChromeVoxState.instance.mode != ChromeVoxMode.FORCE_NEXT)
return;
if (focus) {
var event =
new CustomAutomationEvent(EventType.FOCUS, focus, 'page');
......@@ -137,9 +134,6 @@ DesktopAutomationHandler.prototype = {
ChromeVoxState.instance.setCurrentRange(cursors.Range.fromNode(node));
if (!this.shouldOutput_(evt))
return;
// Don't output if focused node hasn't changed.
if (prevRange && evt.type == 'focus' &&
ChromeVoxState.instance.currentRange.equals(prevRange))
......@@ -162,9 +156,6 @@ DesktopAutomationHandler.prototype = {
* @param {!AutomationEvent} evt
*/
onEventIfInRange: function(evt) {
if (!this.shouldOutput_(evt))
return;
var prev = ChromeVoxState.instance.currentRange;
if (prev.contentEquals(cursors.Range.fromNode(evt.target)) ||
evt.target.state.focused) {
......@@ -245,9 +236,6 @@ DesktopAutomationHandler.prototype = {
*/
onAlert: function(evt) {
var node = evt.target;
if (!node || !this.shouldOutput_(evt))
return;
var range = cursors.Range.fromNode(node);
new Output().withSpeechAndBraille(range, null, evt.type).go();
......@@ -279,9 +267,6 @@ DesktopAutomationHandler.prototype = {
* @param {!AutomationEvent} evt
*/
onChildrenChanged: function(evt) {
if (!this.shouldOutput_(evt))
return;
var curRange = ChromeVoxState.instance.currentRange;
// Always refresh the braille contents.
......@@ -418,9 +403,6 @@ DesktopAutomationHandler.prototype = {
return;
}
if (!this.shouldOutput_(evt))
return;
var t = evt.target;
var fromDesktop = t.root.role == RoleType.DESKTOP;
if (t.state.focused || fromDesktop ||
......@@ -454,7 +436,7 @@ DesktopAutomationHandler.prototype = {
*/
onScrollPositionChanged: function(evt) {
var currentRange = ChromeVoxState.instance.currentRange;
if (currentRange && currentRange.isValid() && this.shouldOutput_(evt))
if (currentRange && currentRange.isValid())
new Output().withLocation(currentRange, null, evt.type).go();
},
......@@ -558,19 +540,6 @@ DesktopAutomationHandler.prototype = {
return !!this.textEditHandler_;
},
/**
* Once an event handler updates ChromeVox's range based on |evt|
* which updates mode, returns whether |evt| should be outputted.
* @return {boolean}
*/
shouldOutput_: function(evt) {
var mode = ChromeVoxState.instance.mode;
// Only output desktop rooted nodes or web nodes for next engine modes.
return evt.target.root.role == RoleType.DESKTOP ||
(mode == ChromeVoxMode.NEXT || mode == ChromeVoxMode.FORCE_NEXT ||
mode == ChromeVoxMode.CLASSIC_COMPAT);
},
/**
* @param {AutomationEvent} evt
* @private
......@@ -611,8 +580,6 @@ DesktopAutomationHandler.prototype = {
}
ChromeVoxState.instance.setCurrentRange(cursors.Range.fromNode(focus));
if (!this.shouldOutput_(evt))
return;
Output.forceModeForNextSpeechUtterance(cvox.QueueMode.FLUSH);
o.withRichSpeechAndBraille(
......
......@@ -11,24 +11,10 @@ goog.require('Output');
goog.scope(function() {
var TreeChangeObserverFilter = chrome.automation.TreeChangeObserverFilter;
/**
* Responds to mode changes.
* @param {ChromeVoxMode} newMode
* @param {?ChromeVoxMode} oldMode Can be null at startup when no range was
* previously set.
*/
FindHandler.onModeChanged = function(newMode, oldMode) {
if (newMode == ChromeVoxMode.FORCE_NEXT)
FindHandler.init_();
else
FindHandler.uninit_();
};
/**
* Initializes this module.
* @private
*/
FindHandler.init_ = function() {
FindHandler.init = function() {
chrome.automation.addTreeChangeObserver(
TreeChangeObserverFilter.TEXT_MARKER_CHANGES, FindHandler.onTextMatch_);
};
......
......@@ -12,9 +12,6 @@ goog.require('cvox.ChromeVoxKbHandler');
/** @constructor */
BackgroundKeyboardHandler = function() {
// Classic keymap.
cvox.ChromeVoxKbHandler.handlerKeyMap = cvox.KeyMap.fromDefaults();
/** @type {number} @private */
this.passThroughKeyUpCount_ = 0;
......@@ -24,7 +21,9 @@ BackgroundKeyboardHandler = function() {
document.addEventListener('keydown', this.onKeyDown.bind(this), false);
document.addEventListener('keyup', this.onKeyUp.bind(this), false);
chrome.accessibilityPrivate.setKeyboardListener(true, false);
chrome.accessibilityPrivate.setKeyboardListener(
true, cvox.ChromeVox.isStickyPrefOn);
window['prefs'].switchToKeyMap('keymap_next');
};
BackgroundKeyboardHandler.prototype = {
......@@ -38,8 +37,7 @@ BackgroundKeyboardHandler.prototype = {
if (cvox.ChromeVox.passThroughMode)
return false;
if (ChromeVoxState.instance.mode != ChromeVoxMode.CLASSIC &&
!cvox.ChromeVoxKbHandler.basicKeyDownActionsListener(evt)) {
if (cvox.ChromeVoxKbHandler.basicKeyDownActionsListener(evt)) {
evt.preventDefault();
evt.stopPropagation();
this.eatenKeyDowns_.add(evt.keyCode);
......@@ -72,32 +70,5 @@ BackgroundKeyboardHandler.prototype = {
}
return false;
},
/**
* React to mode changes.
* @param {ChromeVoxMode} newMode
* @param {ChromeVoxMode?} oldMode
*/
onModeChanged: function(newMode, oldMode) {
if (newMode == ChromeVoxMode.CLASSIC) {
chrome.accessibilityPrivate.setKeyboardListener(false, false);
} else {
chrome.accessibilityPrivate.setKeyboardListener(
true, cvox.ChromeVox.isStickyPrefOn);
}
if (newMode === ChromeVoxMode.NEXT ||
newMode === ChromeVoxMode.FORCE_NEXT) {
// Switching out of classic, classic compat, or uninitialized
// (on startup).
window['prefs'].switchToKeyMap('keymap_next');
} else if (
oldMode && oldMode != ChromeVoxMode.CLASSIC &&
oldMode != ChromeVoxMode.CLASSIC_COMPAT) {
// Switching out of next. Intentionally do nothing when switching out of
// an uninitialized |oldMode|.
window['prefs'].switchToKeyMap('keymap_classic');
}
}
};
......@@ -84,7 +84,7 @@ LiveRegions.prototype = {
var mode = this.chromeVoxState_.mode;
var currentRange = this.chromeVoxState_.currentRange;
if (mode === ChromeVoxMode.CLASSIC || !cvox.ChromeVox.isActive)
if (!cvox.ChromeVox.isActive)
return;
if (!currentRange)
......
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @fileoverview Handles automation from a tabs automation node.
*/
goog.provide('TabsAutomationHandler');
goog.require('CustomAutomationEvent');
goog.require('DesktopAutomationHandler');
goog.scope(function() {
var EventType = chrome.automation.EventType;
var RoleType = chrome.automation.RoleType;
var StateType = chrome.automation.StateType;
/**
* @param {!chrome.automation.AutomationNode} tabRoot
* @constructor
* @extends {DesktopAutomationHandler}
*/
TabsAutomationHandler = function(tabRoot) {
DesktopAutomationHandler.call(this, tabRoot);
if (tabRoot.role != RoleType.ROOT_WEB_AREA)
throw new Error('Expected rootWebArea node but got ' + tabRoot.role);
// When the root is focused, simulate what happens on a load complete.
if (tabRoot.state[StateType.FOCUSED]) {
var event =
new CustomAutomationEvent(EventType.LOAD_COMPLETE, tabRoot, 'page');
this.onLoadComplete(event);
}
};
TabsAutomationHandler.prototype = {
__proto__: DesktopAutomationHandler.prototype,
/** @override */
didHandleEvent_: function(evt) {
evt.stopPropagation();
},
/** @override */
onLoadComplete: function(evt) {
var focused = evt.target.find({state: {focused: true}}) || evt.target;
var event =
new CustomAutomationEvent(EventType.FOCUS, focused, evt.eventFrom);
this.onFocus(event);
}
};
}); // goog.scope
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment