Commit b747ffb1 authored by Akihiro Ota's avatar Akihiro Ota Committed by Commit Bot

Add API to automation to get word start and end indices for string.

This change hooks into AXTextUtils::GetWordBoundariesForString and
exposes this information in automation.

Bug: 948700
Change-Id: I8fe5852cf1ce5e1eeb02e986d4524d44095d054f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1642390Reviewed-by: default avatarDevlin <rdevlin.cronin@chromium.org>
Reviewed-by: default avatarNektarios Paisios <nektar@chromium.org>
Commit-Queue: Akihiro Ota <akihiroota@chromium.org>
Cr-Commit-Position: refs/heads/master@{#668972}
parent 9e04a5e3
...@@ -380,6 +380,13 @@ IN_PROC_BROWSER_TEST_F(AutomationApiTest, HitTest) { ...@@ -380,6 +380,13 @@ IN_PROC_BROWSER_TEST_F(AutomationApiTest, HitTest) {
<< message_; << message_;
} }
IN_PROC_BROWSER_TEST_F(AutomationApiTest, WordBoundaries) {
StartEmbeddedTestServer();
ASSERT_TRUE(
RunExtensionSubtest("automation/tests/tabs", "word_boundaries.html"))
<< message_;
}
class AutomationApiTestWithLanguageDetection : public AutomationApiTest { class AutomationApiTestWithLanguageDetection : public AutomationApiTest {
protected: protected:
void SetUpCommandLine(base::CommandLine* command_line) override { void SetUpCommandLine(base::CommandLine* command_line) override {
......
<!--
* Copyright 2019 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.
-->
<html>
<head>
<title>Automation Tests - Word Boundaries</title>
</head>
<body>
<!-- Used to test wordBoundariesForString. -->
<div role="button">Example text for testing purposes</div>
</body>
</html>
<!--
* Copyright 2019 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.
-->
<script src="common.js"></script>
<script src="word_boundaries.js"></script>
// Copyright 2019 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.
var allTests = [
function testWordStartAndEndOffsets() {
var node = rootNode.find(
{ attributes: { name: 'Example text for testing purposes' } });
var expectedWordStarts = [0, 8, 13, 17, 25];
var expectedWordEnds = [7, 12, 16, 24, 33];
var wordStarts = node.wordStartOffsets();
var wordEnds = node.wordEndOffsets();
assertEq(expectedWordStarts.length, wordStarts.length);
assertEq(expectedWordEnds.length, wordEnds.length);
assertEq(wordStarts.length, wordEnds.length);
for (var i = 0; i < expectedWordStarts.length; ++i){
assertEq(expectedWordStarts[i], wordStarts[i]);
assertEq(expectedWordEnds[i], wordEnds[i]);
}
chrome.test.succeed();
}
];
setUpAndRunTests(allTests, 'word_boundaries.html');
...@@ -589,6 +589,16 @@ ...@@ -589,6 +589,16 @@
long[]? wordStarts; long[]? wordStarts;
long[]? wordEnds; long[]? wordEnds;
// The start index of each word within the node's name. This is different
// from wordStarts because it is not restricted to inline text boxes and can
// be used for any type of element.
long[]? wordStartOffsets;
// The end index of each word within the node's name. This is different
// from wordEnds because it is not restricted to inline text boxes and can
// be used for any type of element.
long[]? wordEndOffsets;
// The nodes, if any, which this node is specified to control via // The nodes, if any, which this node is specified to control via
// <a href="http://www.w3.org/TR/wai-aria/states_and_properties#aria-controls"> // <a href="http://www.w3.org/TR/wai-aria/states_and_properties#aria-controls">
// <code>aria-controls</code></a>. // <code>aria-controls</code></a>.
......
...@@ -41,6 +41,7 @@ ...@@ -41,6 +41,7 @@
#include "ui/accessibility/ax_language_info.h" #include "ui/accessibility/ax_language_info.h"
#include "ui/accessibility/ax_node.h" #include "ui/accessibility/ax_node.h"
#include "ui/accessibility/ax_role_properties.h" #include "ui/accessibility/ax_role_properties.h"
#include "ui/accessibility/ax_text_utils.h"
#include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/l10n_util.h"
#include "ui/gfx/geometry/rect_conversions.h" #include "ui/gfx/geometry/rect_conversions.h"
...@@ -780,6 +781,22 @@ void AutomationInternalCustomBindings::AddRoutes() { ...@@ -780,6 +781,22 @@ void AutomationInternalCustomBindings::AddRoutes() {
response.Set("nodeIds", child_ids); response.Set("nodeIds", child_ids);
result.Set(response.Build()); result.Set(response.Build());
}); });
RouteNodeIDFunction(
"GetWordStartOffsets",
[](v8::Isolate* isolate, v8::ReturnValue<v8::Value> result,
AutomationAXTreeWrapper* tree_wrapper, ui::AXNode* node) {
std::vector<int> word_starts = ui::GetWordStartOffsets(
node->GetString16Attribute(ax::mojom::StringAttribute::kName));
result.Set(gin::ConvertToV8(isolate, word_starts));
});
RouteNodeIDFunction(
"GetWordEndOffsets",
[](v8::Isolate* isolate, v8::ReturnValue<v8::Value> result,
AutomationAXTreeWrapper* tree_wrapper, ui::AXNode* node) {
std::vector<int> word_ends = ui::GetWordEndOffsets(
node->GetString16Attribute(ax::mojom::StringAttribute::kName));
result.Set(gin::ConvertToV8(isolate, word_ends));
});
// Bindings that take a Tree ID and Node ID and string attribute name // Bindings that take a Tree ID and Node ID and string attribute name
// and return a property of the node. // and return a property of the node.
......
...@@ -466,6 +466,20 @@ var GetDetectedLanguage = natives.GetDetectedLanguage; ...@@ -466,6 +466,20 @@ var GetDetectedLanguage = natives.GetDetectedLanguage;
var GetLanguageAnnotationForStringAttribute = var GetLanguageAnnotationForStringAttribute =
natives.GetLanguageAnnotationForStringAttribute; natives.GetLanguageAnnotationForStringAttribute;
/**
* @param {string} axTreeID The id of the accessibility tree.
* @param {number} nodeID The id of a node.
* @return {!Array<number>}
*/
var GetWordStartOffsets = natives.GetWordStartOffsets;
/**
* @param {string} axTreeID The id of the accessibility tree.
* @param {number} nodeID The id of a node.
* @return {!Array<number>}
*/
var GetWordEndOffsets = natives.GetWordEndOffsets;
var logging = requireNative('logging'); var logging = requireNative('logging');
var utils = require('utils'); var utils = require('utils');
...@@ -858,6 +872,14 @@ AutomationNodeImpl.prototype = { ...@@ -858,6 +872,14 @@ AutomationNodeImpl.prototype = {
return impl.get(info.nodeId); return impl.get(info.nodeId);
}, },
wordStartOffsets: function() {
return GetWordStartOffsets(this.treeID, this.id);
},
wordEndOffsets: function() {
return GetWordEndOffsets(this.treeID, this.id);
},
addEventListener: function(eventType, callback, capture) { addEventListener: function(eventType, callback, capture) {
this.removeEventListener(eventType, callback); this.removeEventListener(eventType, callback);
if (!this.listeners[eventType]) if (!this.listeners[eventType])
...@@ -1679,6 +1701,8 @@ utils.expose(AutomationNode, AutomationNodeImpl, { ...@@ -1679,6 +1701,8 @@ utils.expose(AutomationNode, AutomationNodeImpl, {
'toString', 'toString',
'boundsForRange', 'boundsForRange',
'languageAnnotationForStringAttribute', 'languageAnnotationForStringAttribute',
'wordStartOffsets',
'wordEndOffsets',
], ],
readonly: $Array.concat( readonly: $Array.concat(
publicAttributes, publicAttributes,
......
...@@ -651,6 +651,19 @@ chrome.automation.AutomationNode.prototype.wordStarts; ...@@ -651,6 +651,19 @@ chrome.automation.AutomationNode.prototype.wordStarts;
*/ */
chrome.automation.AutomationNode.prototype.wordEnds; chrome.automation.AutomationNode.prototype.wordEnds;
/**
* The start and end index of each word within the node's name. Different from wordStarts and wordEnds because they're not restricted to inline text boxes and can be used for any type of element.
* @type {(!Array<number>|undefined)}
* @see https://developer.chrome.com/extensions/automation#type-wordStartOffsets
*/
chrome.automation.AutomationNode.prototype.wordStartOffsets;
/**
* @type {(!Array<number>|undefined)}
* @see https://developer.chrome.com/extensions/automation#type-wordEndOffsets
*/
chrome.automation.AutomationNode.prototype.wordEndOffsets;
/** /**
* The nodes, if any, which this node is specified to control via <a href="http://www.w3.org/TR/wai-aria/states_and_properties#aria-controls"> <code>aria-controls</code></a>. * The nodes, if any, which this node is specified to control via <a href="http://www.w3.org/TR/wai-aria/states_and_properties#aria-controls"> <code>aria-controls</code></a>.
* @type {(!Array<!chrome.automation.AutomationNode>|undefined)} * @type {(!Array<!chrome.automation.AutomationNode>|undefined)}
......
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