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

Select menu items when moving by object

Bug: 539022
Cq-Include-Trybots: master.tryserver.chromium.linux:closure_compilation
Change-Id: I2e8f9b364e380b8c3200f6674b0ecea859adba01
Reviewed-on: https://chromium-review.googlesource.com/951854
Commit-Queue: David Tseng <dtseng@chromium.org>
Reviewed-by: default avatarMichael Giuffrida <michaelpg@chromium.org>
Cr-Commit-Position: refs/heads/master@{#543184}
parent d2468fc1
...@@ -544,6 +544,11 @@ Background.prototype = { ...@@ -544,6 +544,11 @@ Background.prototype = {
AutomationPredicate.linkOrControl(node); AutomationPredicate.linkOrControl(node);
}; };
// Always try to give nodes selection.
if (start.defaultActionVerb == chrome.automation.DefaultActionVerb.SELECT) {
start.doDefault();
}
// Next, try to focus the start or end node. // Next, try to focus the start or end node.
if (!AutomationPredicate.structuralContainer(start) && if (!AutomationPredicate.structuralContainer(start) &&
start.state[StateType.FOCUSABLE]) { start.state[StateType.FOCUSABLE]) {
......
...@@ -1521,3 +1521,20 @@ TEST_F('BackgroundTest', 'NavigationEscapesEdit', function() { ...@@ -1521,3 +1521,20 @@ TEST_F('BackgroundTest', 'NavigationEscapesEdit', function() {
.replay(); .replay();
}); });
}); });
TEST_F('BackgroundTest', 'NavigationSyncsSelect', function() {
var mockFeedback = this.createMockFeedback();
this.runWithLoadedTree(function() {/*!
<select>
<option>apple</option>
<option>grape</option>
</select>
*/}, function(root) {
var select = root.find({role: RoleType.POP_UP_BUTTON});
mockFeedback.call(select.doDefault.bind(select))
.expectSpeech('apple', 'Selected')
.call(doCmd('nextObject'))
.expectSpeech('grape', 'Selected')
.replay();
});
});
...@@ -279,6 +279,19 @@ ...@@ -279,6 +279,19 @@
readOnly readOnly
}; };
// Describes possible actions when performing a do default action.
enum DefaultActionVerb {
activate,
check,
click,
clickAncestor,
jump,
open,
press,
select,
uncheck
};
dictionary Rect { dictionary Rect {
long left; long left;
long top; long top;
...@@ -494,6 +507,9 @@ ...@@ -494,6 +507,9 @@
// An array of custom actions. // An array of custom actions.
CustomAction[]? customActions; CustomAction[]? customActions;
// The action taken by calling <code>doDefault</code>.
DefaultActionVerb? defaultActionVerb;
// //
// Link attributes. // Link attributes.
// //
......
...@@ -868,6 +868,18 @@ void AutomationInternalCustomBindings::AddRoutes() { ...@@ -868,6 +868,18 @@ void AutomationInternalCustomBindings::AddRoutes() {
result.Set(v8::String::NewFromUtf8(isolate, restriction_str.c_str())); result.Set(v8::String::NewFromUtf8(isolate, restriction_str.c_str()));
} }
}); });
RouteNodeIDFunction(
"GetDefaultActionVerb",
[](v8::Isolate* isolate, v8::ReturnValue<v8::Value> result,
AutomationAXTreeWrapper* tree_wrapper, ui::AXNode* node) {
ax::mojom::DefaultActionVerb default_action_verb =
static_cast<ax::mojom::DefaultActionVerb>(
node->data().GetIntAttribute(
ax::mojom::IntAttribute::kDefaultActionVerb));
std::string default_action_verb_str = ui::ToString(default_action_verb);
result.Set(
v8::String::NewFromUtf8(isolate, default_action_verb_str.c_str()));
});
} }
void AutomationInternalCustomBindings::Invalidate() { void AutomationInternalCustomBindings::Invalidate() {
......
...@@ -314,6 +314,13 @@ var GetLineThrough = natives.GetLineThrough; ...@@ -314,6 +314,13 @@ var GetLineThrough = natives.GetLineThrough;
*/ */
var GetCustomActions = natives.GetCustomActions; var GetCustomActions = natives.GetCustomActions;
/**
* @param {number} axTreeID The id of the accessibility tree.
* @param {number} nodeID The id of a node.
* @return {automation.NameFromType} The source of the node's name.
*/
var GetDefaultActionVerb = natives.GetDefaultActionVerb;
var logging = requireNative('logging'); var logging = requireNative('logging');
var utils = require('utils'); var utils = require('utils');
...@@ -486,6 +493,10 @@ AutomationNodeImpl.prototype = { ...@@ -486,6 +493,10 @@ AutomationNodeImpl.prototype = {
return GetCustomActions(this.treeID, this.id); return GetCustomActions(this.treeID, this.id);
}, },
get defaultActionVerb() {
return GetDefaultActionVerb(this.treeID, this.id);
},
doDefault: function() { doDefault: function() {
this.performAction_('doDefault'); this.performAction_('doDefault');
}, },
...@@ -1360,6 +1371,7 @@ utils.expose(AutomationNode, AutomationNodeImpl, { ...@@ -1360,6 +1371,7 @@ utils.expose(AutomationNode, AutomationNodeImpl, {
'isRootNode', 'isRootNode',
'role', 'role',
'checked', 'checked',
'defaultActionVerb',
'restriction', 'restriction',
'state', 'state',
'location', 'location',
......
...@@ -274,6 +274,22 @@ chrome.automation.Restriction = { ...@@ -274,6 +274,22 @@ chrome.automation.Restriction = {
READ_ONLY: 'readOnly', READ_ONLY: 'readOnly',
}; };
/**
* @enum {string}
* @see https://developer.chrome.com/extensions/automation#type-DefaultActionVerb
*/
chrome.automation.DefaultActionVerb = {
ACTIVATE: 'activate',
CHECK: 'check',
CLICK: 'click',
CLICK_ANCESTOR: 'clickAncestor',
JUMP: 'jump',
OPEN: 'open',
PRESS: 'press',
SELECT: 'select',
UNCHECK: 'uncheck',
};
/** /**
* @typedef {{ * @typedef {{
* left: number, * left: number,
...@@ -618,6 +634,13 @@ chrome.automation.AutomationNode.prototype.labelFor; ...@@ -618,6 +634,13 @@ chrome.automation.AutomationNode.prototype.labelFor;
*/ */
chrome.automation.AutomationNode.prototype.customActions; chrome.automation.AutomationNode.prototype.customActions;
/**
* The action taken by calling <code>doDefault</code>.
* @type {(!chrome.automation.DefaultActionVerb|undefined)}
* @see https://developer.chrome.com/extensions/automation#type-defaultActionVerb
*/
chrome.automation.AutomationNode.prototype.defaultActionVerb;
/** /**
* The URL that this link will navigate to. * The URL that this link will navigate to.
* @type {(string|undefined)} * @type {(string|undefined)}
......
...@@ -121,6 +121,8 @@ def CheckEnumsMatch(input_api, output_api): ...@@ -121,6 +121,8 @@ def CheckEnumsMatch(input_api, output_api):
errs, output_api) errs, output_api)
CheckMatchingEnum(ax_enums, 'Restriction', automation_enums, CheckMatchingEnum(ax_enums, 'Restriction', automation_enums,
'Restriction', errs, output_api) 'Restriction', errs, output_api)
CheckMatchingEnum(ax_enums, 'DefaultActionVerb', automation_enums,
'DefaultActionVerb', errs, output_api)
return errs return errs
# Given a full path to c++ header, return an array of the first static # Given a full path to c++ header, return an array of the first static
......
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