Commit 3019ca46 authored by Zach Helfinstein's avatar Zach Helfinstein Committed by Commit Bot

Allow SwitchAccess to traverse VirtualKeyboard UI

Bug: 864826
Change-Id: Ia594cc934f7c66121ff84660bd1039c5e05213d1
Reviewed-on: https://chromium-review.googlesource.com/1176463
Commit-Queue: Zach Helfinstein <zhelfins@chromium.org>
Reviewed-by: default avatarDavid Tseng <dtseng@chromium.org>
Reviewed-by: default avatarKatie Dektar <katie@chromium.org>
Cr-Commit-Position: refs/heads/master@{#585292}
parent 9fa9364c
...@@ -180,7 +180,9 @@ AutomationManager.prototype = { ...@@ -180,7 +180,9 @@ AutomationManager.prototype = {
SwitchAccessPredicate.restrictions(this.scope_)); SwitchAccessPredicate.restrictions(this.scope_));
// Special case: Scope is actionable. // Special case: Scope is actionable.
if (this.node_ === this.scope_ && !this.visitingScopeAsActionable_) { if (this.node_ === this.scope_ &&
SwitchAccessPredicate.isActionable(this.node_) &&
!this.visitingScopeAsActionable_) {
this.showScopeAsActionable_(); this.showScopeAsActionable_();
return; return;
} }
...@@ -218,7 +220,7 @@ AutomationManager.prototype = { ...@@ -218,7 +220,7 @@ AutomationManager.prototype = {
let node = treeWalker.next().node; let node = treeWalker.next().node;
// Special case: Scope is actionable // Special case: Scope is actionable
if (node === this.scope_) { if (node === this.scope_ && SwitchAccessPredicate.isActionable(node)) {
this.showScopeAsActionable_(); this.showScopeAsActionable_();
return; return;
} }
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
let StateType = chrome.automation.StateType; let StateType = chrome.automation.StateType;
let RoleType = chrome.automation.RoleType; let RoleType = chrome.automation.RoleType;
let DefaultActionVerb = chrome.automation.DefaultActionVerb;
/** /**
* Class containing predicates for the chrome automation API. Each predicate * Class containing predicates for the chrome automation API. Each predicate
...@@ -105,13 +106,15 @@ SwitchAccessPredicate.isGroup = function(node, scope) { ...@@ -105,13 +106,15 @@ SwitchAccessPredicate.isGroup = function(node, scope) {
node !== scope) node !== scope)
return false; return false;
let interestingBranches = 0; let interestingBranchesCount =
let children = node.children || []; SwitchAccessPredicate.isActionable(node) ? 1 : 0;
for (let child of children) { let child = node.firstChild;
while (child) {
if (SwitchAccessPredicate.isInterestingSubtree(child)) if (SwitchAccessPredicate.isInterestingSubtree(child))
interestingBranches += 1; interestingBranchesCount += 1;
if (interestingBranches > 1) if (interestingBranchesCount > 1)
return true; return true;
child = child.nextSibling;
} }
return false; return false;
}; };
...@@ -138,7 +141,7 @@ SwitchAccessPredicate.hasSameLocation_ = function(node1, node2) { ...@@ -138,7 +141,7 @@ SwitchAccessPredicate.hasSameLocation_ = function(node1, node2) {
* @return {boolean} * @return {boolean}
*/ */
SwitchAccessPredicate.isInterestingSubtree = function(node) { SwitchAccessPredicate.isInterestingSubtree = function(node) {
let children = node.children || []; let children = node.children;
return SwitchAccessPredicate.isActionable(node) || return SwitchAccessPredicate.isActionable(node) ||
children.some(SwitchAccessPredicate.isInterestingSubtree); children.some(SwitchAccessPredicate.isInterestingSubtree);
}; };
...@@ -151,28 +154,41 @@ SwitchAccessPredicate.isInterestingSubtree = function(node) { ...@@ -151,28 +154,41 @@ SwitchAccessPredicate.isInterestingSubtree = function(node) {
* @return {boolean} * @return {boolean}
*/ */
SwitchAccessPredicate.isActionable = function(node) { SwitchAccessPredicate.isActionable = function(node) {
let defaultActionVerb = node.defaultActionVerb;
let loc = node.location; let loc = node.location;
let parent = node.parent; let parent = node.parent;
let root = node.root; let root = node.root;
let role = node.role; let role = node.role;
let state = node.state; let state = node.state;
// Skip things that are offscreen // Skip things that are offscreen.
if (state[StateType.OFFSCREEN] || loc.top < 0 || loc.left < 0) if (state[StateType.OFFSCREEN] || loc.top < 0 || loc.left < 0)
return false; return false;
// Should just leave these as groups // These web containers are not directly actionable.
if (role === RoleType.WEB_VIEW || role === RoleType.ROOT_WEB_AREA) if (role === RoleType.WEB_VIEW || role === RoleType.ROOT_WEB_AREA)
return false; return false;
if (parent) { if (parent) {
// crbug.com/710559 // crbug.com/710559
// Work around for browser tabs // Work around for browser tabs.
if (role === RoleType.TAB && parent.role === RoleType.TAB_LIST && if (role === RoleType.TAB && parent.role === RoleType.TAB_LIST &&
root.role === RoleType.DESKTOP) root.role === RoleType.DESKTOP)
return true; return true;
} }
// The general rule that applies to everything. // Check various indicators that the node is actionable.
return state[StateType.FOCUSABLE]; // TODO(zhelfins): Update tests to reflect this updated behavior.
if (defaultActionVerb && defaultActionVerb !== 'none' &&
defaultActionVerb !== DefaultActionVerb.CLICK_ANCESTOR)
return true;
if (node.inputType)
return true;
if (role === RoleType.BUTTON)
return true;
return false;
}; };
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