summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordtseng <dtseng@chromium.org>2015-06-26 10:58:46 -0700
committerCommit bot <commit-bot@chromium.org>2015-06-26 17:59:14 +0000
commit911ea803dbd347a95ca49f4d46ad4c2e1ab06ac1 (patch)
treee1f7825d144bbc9f8230d3f89f643512328850fa
parentd3639a0b90860d03afa59a06c6635d7af23111d1 (diff)
downloadchromium_src-911ea803dbd347a95ca49f4d46ad4c2e1ab06ac1.zip
chromium_src-911ea803dbd347a95ca49f4d46ad4c2e1ab06ac1.tar.gz
chromium_src-911ea803dbd347a95ca49f4d46ad4c2e1ab06ac1.tar.bz2
Reland: Support Compat mode inside of the desktop tree.
Originalcommit: https://crrev.com/e7b1c72c03dcf636e50917b2c8122e5d0ef884b6 TEST=interactive_ui_tests --gtest_filter=SpokenFeedbackTest.* TBR=dtseng@chromium.org Review URL: https://codereview.chromium.org/1214503003 Cr-Commit-Position: refs/heads/master@{#336406}
-rw-r--r--ash/accelerators/accelerator_controller.cc40
-rw-r--r--ash/accelerators/accelerator_table.cc7
-rw-r--r--ash/accelerators/accelerator_table.h2
-rw-r--r--chrome/browser/chromeos/accessibility/spoken_feedback_browsertest.cc15
-rw-r--r--chrome/browser/resources/chromeos/chromevox/cvox2/background/background.js54
-rw-r--r--chrome/browser/resources/chromeos/chromevox/cvox2/background/classic_compatibility.js74
-rw-r--r--chrome/browser/resources/chromeos/chromevox/host/chrome/host.js3
7 files changed, 107 insertions, 88 deletions
diff --git a/ash/accelerators/accelerator_controller.cc b/ash/accelerators/accelerator_controller.cc
index 6eb68a3..8f1d947 100644
--- a/ash/accelerators/accelerator_controller.cc
+++ b/ash/accelerators/accelerator_controller.cc
@@ -79,37 +79,6 @@ namespace {
using base::UserMetricsAction;
-bool CanHandleAccessibleFocusCycle() {
- if (!Shell::GetInstance()->accessibility_delegate()->
- IsSpokenFeedbackEnabled()) {
- return false;
- }
- aura::Window* active_window = ash::wm::GetActiveWindow();
- if (!active_window)
- return false;
- views::Widget* widget =
- views::Widget::GetWidgetForNativeWindow(active_window);
- if (!widget)
- return false;
- views::FocusManager* focus_manager = widget->GetFocusManager();
- if (!focus_manager)
- return false;
- views::View* view = focus_manager->GetFocusedView();
- return view && strcmp(view->GetClassName(), views::WebView::kViewClassName);
-}
-
-void HandleAccessibleFocusCycle(bool reverse) {
- if (reverse)
- base::RecordAction(UserMetricsAction("Accel_Accessible_Focus_Previous"));
- else
- base::RecordAction(UserMetricsAction("Accel_Accessible_Focus_Next"));
-
- aura::Window* active_window = ash::wm::GetActiveWindow();
- views::Widget* widget =
- views::Widget::GetWidgetForNativeWindow(active_window);
- widget->GetFocusManager()->AdvanceFocus(reverse);
-}
-
void HandleCycleBackwardMRU(const ui::Accelerator& accelerator) {
if (accelerator.key_code() == ui::VKEY_TAB)
base::RecordAction(base::UserMetricsAction("Accel_PrevWindow_Tab"));
@@ -880,9 +849,6 @@ bool AcceleratorController::CanPerformAction(
// false should be returned to give the web contents a chance at handling the
// accelerator.
switch (action) {
- case ACCESSIBLE_FOCUS_NEXT:
- case ACCESSIBLE_FOCUS_PREVIOUS:
- return CanHandleAccessibleFocusCycle();
case DEBUG_PRINT_LAYER_HIERARCHY:
case DEBUG_PRINT_VIEW_HIERARCHY:
case DEBUG_PRINT_WINDOW_HIERARCHY:
@@ -1013,12 +979,6 @@ void AcceleratorController::PerformAction(AcceleratorAction action,
// implement it in your module's controller code (like TOGGLE_MIRROR_MODE
// below) or pull it into a HandleFoo() function above.
switch (action) {
- case ACCESSIBLE_FOCUS_NEXT:
- HandleAccessibleFocusCycle(false);
- break;
- case ACCESSIBLE_FOCUS_PREVIOUS:
- HandleAccessibleFocusCycle(true);
- break;
case CYCLE_BACKWARD_MRU:
HandleCycleBackwardMRU(accelerator);
break;
diff --git a/ash/accelerators/accelerator_table.cc b/ash/accelerators/accelerator_table.cc
index 93ddb01..446819c 100644
--- a/ash/accelerators/accelerator_table.cc
+++ b/ash/accelerators/accelerator_table.cc
@@ -171,11 +171,6 @@ const AcceleratorData kAcceleratorData[] = {
{ true, ui::VKEY_U, ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN | ui::EF_SHIFT_DOWN,
PRINT_UI_HIERARCHIES },
- { false, ui::VKEY_HOME, ui::EF_SHIFT_DOWN, ACCESSIBLE_FOCUS_PREVIOUS},
- { false, ui::VKEY_PRIOR, ui::EF_SHIFT_DOWN, ACCESSIBLE_FOCUS_PREVIOUS},
- { false, ui::VKEY_END, ui::EF_SHIFT_DOWN, ACCESSIBLE_FOCUS_NEXT},
- { false, ui::VKEY_NEXT, ui::EF_SHIFT_DOWN, ACCESSIBLE_FOCUS_NEXT},
-
// TODO(yusukes): Handle VKEY_MEDIA_STOP, and
// VKEY_MEDIA_LAUNCH_MAIL.
};
@@ -408,8 +403,6 @@ const size_t kActionsAllowedInAppModeLength =
arraysize(kActionsAllowedInAppMode);
const AcceleratorAction kActionsNeedingWindow[] = {
- ACCESSIBLE_FOCUS_NEXT,
- ACCESSIBLE_FOCUS_PREVIOUS,
CYCLE_BACKWARD_MRU,
CYCLE_FORWARD_MRU,
TOGGLE_OVERVIEW,
diff --git a/ash/accelerators/accelerator_table.h b/ash/accelerators/accelerator_table.h
index 1d478a0..86ec318 100644
--- a/ash/accelerators/accelerator_table.h
+++ b/ash/accelerators/accelerator_table.h
@@ -51,8 +51,6 @@ namespace ash {
// Please put if/def sections at the end of the bare section and keep the list
// within each section in alphabetical order.
enum AcceleratorAction {
- ACCESSIBLE_FOCUS_NEXT,
- ACCESSIBLE_FOCUS_PREVIOUS,
CYCLE_BACKWARD_MRU,
CYCLE_FORWARD_MRU,
DEBUG_PRINT_LAYER_HIERARCHY,
diff --git a/chrome/browser/chromeos/accessibility/spoken_feedback_browsertest.cc b/chrome/browser/chromeos/accessibility/spoken_feedback_browsertest.cc
index 9fb3b46..942f257 100644
--- a/chrome/browser/chromeos/accessibility/spoken_feedback_browsertest.cc
+++ b/chrome/browser/chromeos/accessibility/spoken_feedback_browsertest.cc
@@ -355,6 +355,21 @@ IN_PROC_BROWSER_TEST_P(SpokenFeedbackTest, NavigateSystemTray) {
break;
}
+ SendKeyPress(ui::VKEY_TAB);
+ EXPECT_TRUE(MatchPattern(speech_monitor_.GetNextUtterance(), "*"));
+ EXPECT_TRUE(MatchPattern(speech_monitor_.GetNextUtterance(), "Button"));
+
+ // Compat next element.
+ SendKeyPressWithSearchAndShift(ui::VKEY_RIGHT);
+ EXPECT_TRUE(MatchPattern(speech_monitor_.GetNextUtterance(), "*"));
+ EXPECT_TRUE(MatchPattern(speech_monitor_.GetNextUtterance(), "Button"));
+
+ // Compat next button.
+ SendKeyPressWithSearchAndShift(ui::VKEY_N);
+ SendKeyPressWithSearchAndShift(ui::VKEY_B);
+ EXPECT_TRUE(MatchPattern(speech_monitor_.GetNextUtterance(), "*"));
+ EXPECT_TRUE(MatchPattern(speech_monitor_.GetNextUtterance(), "Button"));
+
// Navigate to Bluetooth sub-menu and open it.
while (true) {
SendKeyPress(ui::VKEY_TAB);
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/background.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/background.js
index 8d988b5..59b90f3 100644
--- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/background.js
+++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/background.js
@@ -61,7 +61,7 @@ Background = function() {
this.mode_ = ChromeVoxMode.CLASSIC;
/** @type {!ClassicCompatibility} @private */
- this.compat_ = new ClassicCompatibility(this.mode_ === ChromeVoxMode.COMPAT);
+ this.compat_ = new ClassicCompatibility();
// Manually bind all functions to |this|.
for (var func in this) {
@@ -86,8 +86,6 @@ Background = function() {
valueChanged: this.onValueChanged
};
- // Register listeners for ...
- // Desktop.
chrome.automation.getDesktop(this.onGotDesktop);
};
@@ -127,18 +125,15 @@ Background.prototype = {
* @param {string} command
* @param {boolean=} opt_skipCompat Whether to skip compatibility checks.
*/
- onGotCommand: function(command, opt_skipCompat) {
+ onGotCommand: function(command, opt_skipCompat) {
if (!this.currentRange_)
return;
- if (!opt_skipCompat) {
+ if (!opt_skipCompat && this.mode_ === ChromeVoxMode.COMPAT) {
if (this.compat_.onGotCommand(command))
return;
}
- if (this.mode_ === ChromeVoxMode.CLASSIC)
- return;
-
var current = this.currentRange_;
var dir = Dir.FORWARD;
var pred = null;
@@ -328,10 +323,14 @@ Background.prototype = {
if (current) {
// TODO(dtseng): Figure out what it means to focus a range.
- current.getStart().getNode().focus();
+ var actionNode = current.getStart().getNode();
+ if (actionNode.role == chrome.automation.RoleType.inlineTextBox)
+ actionNode = actionNode.parent;
+ actionNode.focus();
var prevRange = this.currentRange_;
this.currentRange_ = current;
+
new Output().withSpeechAndBraille(
this.currentRange_, prevRange, Output.EventType.NAVIGATE)
.go();
@@ -352,10 +351,12 @@ Background.prototype = {
this.currentRange_ = cursors.Range.fromNode(node);
- // Check to see if we've crossed roots. Only care about focused roots.
- if (!prevRange ||
+ // Check to see if we've crossed roots. Continue if we've crossed roots or
+ // are not within web content.
+ if (node.root.role == 'desktop' ||
+ !prevRange ||
(prevRange.getStart().getNode().root != node.root &&
- node.root.focused))
+ node.state.focused))
this.setupChromeVoxVariants_(node.root.docUrl || '');
// Don't process nodes inside of web content if ChromeVox Next is inactive.
@@ -365,6 +366,12 @@ Background.prototype = {
return;
}
+ // Don't output if focused node hasn't changed.
+ if (prevRange &&
+ evt.type == 'focus' &&
+ this.currentRange_.equals(prevRange))
+ return;
+
new Output().withSpeechAndBraille(
this.currentRange_, prevRange, evt.type)
.go();
@@ -512,7 +519,7 @@ Background.prototype = {
* @private
*/
isWhitelistedForCompat_: function(url) {
- return url.indexOf('chrome://md-settings') != -1;
+ return url.indexOf('chrome://md-settings') != -1 || url === '';
},
/**
@@ -532,14 +539,15 @@ Background.prototype = {
* @private
*/
setupChromeVoxVariants_: function(url) {
- this.compat_.active = this.isWhitelistedForCompat_(url);
var mode = this.mode_;
- if (this.compat_.active)
- mode = ChromeVoxMode.COMPAT;
- else if (this.isWhitelistedForNext_(url))
- mode = ChromeVoxMode.NEXT;
- else if (mode != ChromeVoxMode.FORCE_NEXT)
- mode = ChromeVoxMode.CLASSIC;
+ if (mode != ChromeVoxMode.FORCE_NEXT) {
+ if (this.isWhitelistedForCompat_(url))
+ mode = ChromeVoxMode.COMPAT;
+ else if (this.isWhitelistedForNext_(url))
+ mode = ChromeVoxMode.NEXT;
+ else
+ mode = ChromeVoxMode.CLASSIC;
+ }
this.setChromeVoxMode(mode);
},
@@ -577,13 +585,17 @@ Background.prototype = {
// for tabs, re-enable.
// 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_.getStart().getNode().root.role == 'desktop')
+ return;
+
tabs.forEach(function(tab) {
this.disableClassicChromeVox_(tab.id);
}.bind(this));
}
}.bind(this));
- this.compat_.active = mode === ChromeVoxMode.COMPAT;
this.mode_ = mode;
}
};
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/classic_compatibility.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/classic_compatibility.js
index dae832c..a5a063e 100644
--- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/classic_compatibility.js
+++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/classic_compatibility.js
@@ -9,19 +9,16 @@
goog.provide('ClassicCompatibility');
+goog.require('cvox.ExtensionBridge');
goog.require('cvox.KeyMap');
goog.require('cvox.KeySequence');
goog.require('cvox.KeyUtil');
goog.require('cvox.SimpleKeyEvent');
/**
- * @param {boolean=} opt_active Whether compatibility is currently active.
* @constructor
*/
-var ClassicCompatibility = function(opt_active) {
- /** @type {boolean} */
- this.active = !!opt_active;
-
+var ClassicCompatibility = function() {
/**
* @type {!Array<{description: string, name: string, shortcut: string}>}
* @private
@@ -31,9 +28,15 @@ var ClassicCompatibility = function(opt_active) {
/** @type {!cvox.KeyMap} */
this.keyMap = cvox.KeyMap.fromCurrentKeyMap();
- chrome.commands.getAll(function(commands) {
- this.commands_ = commands;
- }.bind(this));
+ // We grab the list of commands from the manifest because
+ // chrome.commands.getAll is buggy.
+ /** @type {!Object} */
+ var commands = chrome.runtime.getManifest()['commands'];
+ for (var key in commands) {
+ /** @type {{suggested_key: {chromeos: string}}} */
+ var command = commands[key];
+ this.commands_.push({name: key, shortcut: command.suggested_key.chromeos});
+ }
};
ClassicCompatibility.prototype = {
@@ -43,25 +46,45 @@ ClassicCompatibility.prototype = {
* @return {boolean} Whether the command was successfully processed.
*/
onGotCommand: function(command) {
- if (!this.active)
+ var evt = this.buildKeyEvent_(command);
+ if (!evt)
+ return false;
+ this.simulateKeyDownNext_(evt);
+ return true;
+ },
+
+ /**
+ * Processes a ChromeVox Next command while in CLASSIC mode.
+ * @param {string} command
+ * @return {boolean} Whether the command was successfully processed.
+ */
+ onGotClassicCommand: function(command) {
+ var evt = this.buildKeyEvent_(command);
+ if (!evt)
return false;
+ this.simulateKeyDownClassic_(evt);
+ return true;
+ },
+ /**
+ * @param {string} command
+ * @return {cvox.SimpleKeyEvent?}
+ */
+ buildKeyEvent_: function(command) {
var commandInfo = this.commands_.filter(function(c) {
return c.name == command;
}.bind(this))[0];
if (!commandInfo)
- return false;
+ return null;
var shortcut = commandInfo.shortcut;
- var evt = this.convertCommandShortcutToKeyEvent_(shortcut);
- this.simulateKeyDown_(evt);
- return true;
+ return this.convertCommandShortcutToKeyEvent_(shortcut);
},
/**
* @param {cvox.SimpleKeyEvent} evt
* @private
*/
- simulateKeyDown_: function(evt) {
+ simulateKeyDownNext_: function(evt) {
var keySequence = cvox.KeyUtil.keyEventToKeySequence(evt);
var classicCommand = this.keyMap.commandForKey(keySequence);
if (classicCommand) {
@@ -72,6 +95,21 @@ ClassicCompatibility.prototype = {
},
/**
+ * @param {cvox.SimpleKeyEvent} evt
+ * @private
+ */
+ simulateKeyDownClassic_: function(evt) {
+ var keySequence = cvox.KeyUtil.keyEventToKeySequence(evt);
+ var classicCommand = this.keyMap.commandForKey(keySequence);
+ if (classicCommand) {
+ cvox.ExtensionBridge.send({
+ 'message': 'USER_COMMAND',
+ 'command': classicCommand
+ });
+ }
+ },
+
+ /**
* @param {string} shortcut
* @return {cvox.SimpleKeyEvent}
* @private
@@ -96,16 +134,16 @@ ClassicCompatibility.prototype = {
case 'Space':
evt.keyCode = 32;
break;
- case 'Left Arrow':
+ case 'Left':
evt.keyCode = 37;
break;
- case 'Up Arrow':
+ case 'Up':
evt.keyCode = 38;
break;
- case 'Right Arrow':
+ case 'Right':
evt.keyCode = 39;
break;
- case 'Down Arrow':
+ case 'Down':
evt.keyCode = 40;
break;
default:
diff --git a/chrome/browser/resources/chromeos/chromevox/host/chrome/host.js b/chrome/browser/resources/chromeos/chromevox/host/chrome/host.js
index 19cdfb7..7fbe95b 100644
--- a/chrome/browser/resources/chromeos/chromevox/host/chrome/host.js
+++ b/chrome/browser/resources/chromeos/chromevox/host/chrome/host.js
@@ -125,6 +125,9 @@ cvox.ChromeHost.prototype.init = function() {
var message = msg['message'];
if (message == 'USER_COMMAND') {
var cmd = msg['command'];
+ if (cmd != 'toggleChromeVox' && !cvox.ChromeVox.documentHasFocus()) {
+ return;
+ }
cvox.ChromeVoxUserCommands.commands[cmd](msg);
}
});