Commit 9b4cbe49 authored by Alexander Surkov's avatar Alexander Surkov Committed by Commit Bot

Port ax_dump_tree tool on mac: generalize LineIndexesMap to reuse it for...

Port ax_dump_tree tool on mac: generalize LineIndexesMap to reuse it for native mac accessible trees

Bug: 1124366
Change-Id: Id0071572ef54856fee9f6ecd1b5d379fdbb3a079
AX-Relnotes: n/a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2391468
Commit-Queue: Alexander Surkov <asurkov@igalia.com>
Reviewed-by: default avatarDominic Mazzoni <dmazzoni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#804455}
parent 8f6bd292
...@@ -25,7 +25,8 @@ using base::SysNSStringToUTF8; ...@@ -25,7 +25,8 @@ using base::SysNSStringToUTF8;
using base::SysNSStringToUTF16; using base::SysNSStringToUTF16;
using base::SysUTF16ToNSString; using base::SysUTF16ToNSString;
using std::string; using std::string;
using content::a11y::LineIndexesMap; using content::a11y::LineIndexer;
using content::a11y::CocoaLineIndexer;
using content::a11y::OptionalNSObject; using content::a11y::OptionalNSObject;
using content::a11y::AttributeInvoker; using content::a11y::AttributeInvoker;
...@@ -69,7 +70,7 @@ class AccessibilityTreeFormatterMac : public AccessibilityTreeFormatterBase { ...@@ -69,7 +70,7 @@ class AccessibilityTreeFormatterMac : public AccessibilityTreeFormatterBase {
private: private:
void RecursiveBuildAccessibilityTree(const BrowserAccessibilityCocoa* node, void RecursiveBuildAccessibilityTree(const BrowserAccessibilityCocoa* node,
const LineIndexesMap& line_indexes_map, const LineIndexer* line_indexer,
base::DictionaryValue* dict); base::DictionaryValue* dict);
base::FilePath::StringType GetExpectedFileSuffix() override; base::FilePath::StringType GetExpectedFileSuffix() override;
...@@ -80,27 +81,26 @@ class AccessibilityTreeFormatterMac : public AccessibilityTreeFormatterBase { ...@@ -80,27 +81,26 @@ class AccessibilityTreeFormatterMac : public AccessibilityTreeFormatterBase {
const std::string GetRunUntilEventString() override; const std::string GetRunUntilEventString() override;
void AddProperties(const BrowserAccessibilityCocoa* node, void AddProperties(const BrowserAccessibilityCocoa* node,
const LineIndexesMap& line_indexes_map, const LineIndexer* line_indexer,
base::Value* dict); base::Value* dict);
// Invokes an attributes by a property node. // Invokes an attributes by a property node.
OptionalNSObject InvokeAttributeFor( OptionalNSObject InvokeAttributeFor(
const BrowserAccessibilityCocoa* cocoa_node, const BrowserAccessibilityCocoa* cocoa_node,
const PropertyNode& property_node, const PropertyNode& property_node,
const LineIndexesMap& line_indexes_map) const; const LineIndexer* line_indexer) const;
base::Value PopulateSize(const BrowserAccessibilityCocoa*) const; base::Value PopulateSize(const BrowserAccessibilityCocoa*) const;
base::Value PopulatePosition(const BrowserAccessibilityCocoa*) const; base::Value PopulatePosition(const BrowserAccessibilityCocoa*) const;
base::Value PopulateRange(NSRange) const; base::Value PopulateRange(NSRange) const;
base::Value PopulateTextPosition( base::Value PopulateTextPosition(
BrowserAccessibilityPosition::AXPositionInstance::pointer, BrowserAccessibilityPosition::AXPositionInstance::pointer,
const LineIndexesMap&) const; const LineIndexer*) const;
base::Value PopulateTextMarkerRange(id, const LineIndexesMap&) const; base::Value PopulateTextMarkerRange(id, const LineIndexer*) const;
base::Value PopulateObject(id, const LineIndexesMap& line_indexes_map) const; base::Value PopulateObject(id, const LineIndexer* line_indexer) const;
base::Value PopulateArray(NSArray*, base::Value PopulateArray(NSArray*, const LineIndexer* line_indexer) const;
const LineIndexesMap& line_indexes_map) const;
std::string NodeToLineIndex(id, const LineIndexesMap&) const; std::string NodeToLineIndex(id, const LineIndexer*) const;
std::string ProcessTreeForOutput( std::string ProcessTreeForOutput(
const base::DictionaryValue& node, const base::DictionaryValue& node,
...@@ -148,13 +148,10 @@ std::unique_ptr<base::DictionaryValue> ...@@ -148,13 +148,10 @@ std::unique_ptr<base::DictionaryValue>
AccessibilityTreeFormatterMac::BuildAccessibilityTree( AccessibilityTreeFormatterMac::BuildAccessibilityTree(
BrowserAccessibility* root) { BrowserAccessibility* root) {
DCHECK(root); DCHECK(root);
BrowserAccessibilityCocoa* cocoa_root = ToBrowserAccessibilityCocoa(root); BrowserAccessibilityCocoa* cocoa_root = ToBrowserAccessibilityCocoa(root);
CocoaLineIndexer line_indexer(cocoa_root);
LineIndexesMap line_indexes_map(cocoa_root);
std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue); std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue);
RecursiveBuildAccessibilityTree(cocoa_root, line_indexes_map, dict.get()); RecursiveBuildAccessibilityTree(cocoa_root, &line_indexer, dict.get());
return dict; return dict;
} }
...@@ -181,15 +178,15 @@ AccessibilityTreeFormatterMac::BuildAccessibilityTreeForPattern( ...@@ -181,15 +178,15 @@ AccessibilityTreeFormatterMac::BuildAccessibilityTreeForPattern(
void AccessibilityTreeFormatterMac::RecursiveBuildAccessibilityTree( void AccessibilityTreeFormatterMac::RecursiveBuildAccessibilityTree(
const BrowserAccessibilityCocoa* cocoa_node, const BrowserAccessibilityCocoa* cocoa_node,
const LineIndexesMap& line_indexes_map, const LineIndexer* line_indexer,
base::DictionaryValue* dict) { base::DictionaryValue* dict) {
AddProperties(cocoa_node, line_indexes_map, dict); AddProperties(cocoa_node, line_indexer, dict);
auto children = std::make_unique<base::ListValue>(); auto children = std::make_unique<base::ListValue>();
for (BrowserAccessibilityCocoa* cocoa_child in [cocoa_node children]) { for (BrowserAccessibilityCocoa* cocoa_child in [cocoa_node children]) {
std::unique_ptr<base::DictionaryValue> child_dict( std::unique_ptr<base::DictionaryValue> child_dict(
new base::DictionaryValue); new base::DictionaryValue);
RecursiveBuildAccessibilityTree(cocoa_child, line_indexes_map, RecursiveBuildAccessibilityTree(cocoa_child, line_indexer,
child_dict.get()); child_dict.get());
children->Append(std::move(child_dict)); children->Append(std::move(child_dict));
} }
...@@ -198,7 +195,7 @@ void AccessibilityTreeFormatterMac::RecursiveBuildAccessibilityTree( ...@@ -198,7 +195,7 @@ void AccessibilityTreeFormatterMac::RecursiveBuildAccessibilityTree(
void AccessibilityTreeFormatterMac::AddProperties( void AccessibilityTreeFormatterMac::AddProperties(
const BrowserAccessibilityCocoa* cocoa_node, const BrowserAccessibilityCocoa* cocoa_node,
const LineIndexesMap& line_indexes_map, const LineIndexer* line_indexer,
base::Value* dict) { base::Value* dict) {
// DOM element id // DOM element id
BrowserAccessibility* node = [cocoa_node owner]; BrowserAccessibility* node = [cocoa_node owner];
...@@ -210,15 +207,15 @@ void AccessibilityTreeFormatterMac::AddProperties( ...@@ -210,15 +207,15 @@ void AccessibilityTreeFormatterMac::AddProperties(
dict->SetPath( dict->SetPath(
SysNSStringToUTF8(attribute), SysNSStringToUTF8(attribute),
PopulateObject([cocoa_node accessibilityAttributeValue:attribute], PopulateObject([cocoa_node accessibilityAttributeValue:attribute],
line_indexes_map)); line_indexer));
} }
return; return;
} }
// Otherwise dump attributes matching allow filters only. // Otherwise dump attributes matching allow filters only.
std::string line_index = line_indexes_map.IndexBy(cocoa_node); std::string line_index = line_indexer->IndexBy(cocoa_node);
for (const PropertyNode& property_node : PropertyFilterNodesFor(line_index)) { for (const PropertyNode& property_node : PropertyFilterNodesFor(line_index)) {
AttributeInvoker invoker(cocoa_node, line_indexes_map); AttributeInvoker invoker(cocoa_node, line_indexer);
OptionalNSObject value = invoker.Invoke(property_node); OptionalNSObject value = invoker.Invoke(property_node);
if (value.IsNotApplicable()) { if (value.IsNotApplicable()) {
continue; continue;
...@@ -229,7 +226,7 @@ void AccessibilityTreeFormatterMac::AddProperties( ...@@ -229,7 +226,7 @@ void AccessibilityTreeFormatterMac::AddProperties(
continue; continue;
} }
dict->SetPath(property_node.original_property, dict->SetPath(property_node.original_property,
PopulateObject(*value, line_indexes_map)); PopulateObject(*value, line_indexer));
} }
// Position and size // Position and size
...@@ -277,14 +274,14 @@ base::Value AccessibilityTreeFormatterMac::PopulatePosition( ...@@ -277,14 +274,14 @@ base::Value AccessibilityTreeFormatterMac::PopulatePosition(
base::Value AccessibilityTreeFormatterMac::PopulateObject( base::Value AccessibilityTreeFormatterMac::PopulateObject(
id value, id value,
const LineIndexesMap& line_indexes_map) const { const LineIndexer* line_indexer) const {
if (value == nil) { if (value == nil) {
return base::Value(kNULLValue); return base::Value(kNULLValue);
} }
// NSArray // NSArray
if ([value isKindOfClass:[NSArray class]]) { if ([value isKindOfClass:[NSArray class]]) {
return PopulateArray((NSArray*)value, line_indexes_map); return PopulateArray((NSArray*)value, line_indexer);
} }
// NSNumber // NSNumber
...@@ -301,17 +298,17 @@ base::Value AccessibilityTreeFormatterMac::PopulateObject( ...@@ -301,17 +298,17 @@ base::Value AccessibilityTreeFormatterMac::PopulateObject(
// AXTextMarker // AXTextMarker
if (content::IsAXTextMarker(value)) { if (content::IsAXTextMarker(value)) {
return PopulateTextPosition(content::AXTextMarkerToPosition(value).get(), return PopulateTextPosition(content::AXTextMarkerToPosition(value).get(),
line_indexes_map); line_indexer);
} }
// AXTextMarkerRange // AXTextMarkerRange
if (content::IsAXTextMarkerRange(value)) { if (content::IsAXTextMarkerRange(value)) {
return PopulateTextMarkerRange(value, line_indexes_map); return PopulateTextMarkerRange(value, line_indexer);
} }
// Accessible object // Accessible object
if ([value isKindOfClass:[BrowserAccessibilityCocoa class]]) { if ([value isKindOfClass:[BrowserAccessibilityCocoa class]]) {
return base::Value(NodeToLineIndex(value, line_indexes_map)); return base::Value(NodeToLineIndex(value, line_indexer));
} }
// Scalar value. // Scalar value.
...@@ -329,7 +326,7 @@ base::Value AccessibilityTreeFormatterMac::PopulateRange( ...@@ -329,7 +326,7 @@ base::Value AccessibilityTreeFormatterMac::PopulateRange(
base::Value AccessibilityTreeFormatterMac::PopulateTextPosition( base::Value AccessibilityTreeFormatterMac::PopulateTextPosition(
BrowserAccessibilityPosition::AXPositionInstance::pointer position, BrowserAccessibilityPosition::AXPositionInstance::pointer position,
const LineIndexesMap& line_indexes_map) const { const LineIndexer* line_indexer) const {
if (position->IsNullPosition()) { if (position->IsNullPosition()) {
return base::Value(kNULLValue); return base::Value(kNULLValue);
} }
...@@ -353,7 +350,7 @@ base::Value AccessibilityTreeFormatterMac::PopulateTextPosition( ...@@ -353,7 +350,7 @@ base::Value AccessibilityTreeFormatterMac::PopulateTextPosition(
base::Value set(base::Value::Type::DICTIONARY); base::Value set(base::Value::Type::DICTIONARY);
const std::string setkey_prefix = kSetKeyPrefixDictAttr; const std::string setkey_prefix = kSetKeyPrefixDictAttr;
set.SetStringPath(setkey_prefix + "index1_anchor", set.SetStringPath(setkey_prefix + "index1_anchor",
NodeToLineIndex(cocoa_anchor, line_indexes_map)); NodeToLineIndex(cocoa_anchor, line_indexer));
set.SetIntPath(setkey_prefix + "index2_offset", position->text_offset()); set.SetIntPath(setkey_prefix + "index2_offset", position->text_offset());
set.SetStringPath(setkey_prefix + "index3_affinity", set.SetStringPath(setkey_prefix + "index3_affinity",
kConstValuePrefix + affinity); kConstValuePrefix + affinity);
...@@ -362,32 +359,31 @@ base::Value AccessibilityTreeFormatterMac::PopulateTextPosition( ...@@ -362,32 +359,31 @@ base::Value AccessibilityTreeFormatterMac::PopulateTextPosition(
base::Value AccessibilityTreeFormatterMac::PopulateTextMarkerRange( base::Value AccessibilityTreeFormatterMac::PopulateTextMarkerRange(
id object, id object,
const LineIndexesMap& line_indexes_map) const { const LineIndexer* line_indexer) const {
auto range = content::AXTextMarkerRangeToRange(object); auto range = content::AXTextMarkerRangeToRange(object);
if (range.IsNull()) { if (range.IsNull()) {
return base::Value(kNULLValue); return base::Value(kNULLValue);
} }
base::Value dict(base::Value::Type::DICTIONARY); base::Value dict(base::Value::Type::DICTIONARY);
dict.SetPath("anchor", dict.SetPath("anchor", PopulateTextPosition(range.anchor(), line_indexer));
PopulateTextPosition(range.anchor(), line_indexes_map)); dict.SetPath("focus", PopulateTextPosition(range.focus(), line_indexer));
dict.SetPath("focus", PopulateTextPosition(range.focus(), line_indexes_map));
return dict; return dict;
} }
base::Value AccessibilityTreeFormatterMac::PopulateArray( base::Value AccessibilityTreeFormatterMac::PopulateArray(
NSArray* node_array, NSArray* node_array,
const LineIndexesMap& line_indexes_map) const { const LineIndexer* line_indexer) const {
base::Value list(base::Value::Type::LIST); base::Value list(base::Value::Type::LIST);
for (NSUInteger i = 0; i < [node_array count]; i++) for (NSUInteger i = 0; i < [node_array count]; i++)
list.Append(PopulateObject([node_array objectAtIndex:i], line_indexes_map)); list.Append(PopulateObject([node_array objectAtIndex:i], line_indexer));
return list; return list;
} }
std::string AccessibilityTreeFormatterMac::NodeToLineIndex( std::string AccessibilityTreeFormatterMac::NodeToLineIndex(
id cocoa_node, id cocoa_node,
const LineIndexesMap& line_indexes_map) const { const LineIndexer* line_indexer) const {
return kConstValuePrefix + line_indexes_map.IndexBy(cocoa_node); return kConstValuePrefix + line_indexer->IndexBy(cocoa_node);
} }
std::string AccessibilityTreeFormatterMac::ProcessTreeForOutput( std::string AccessibilityTreeFormatterMac::ProcessTreeForOutput(
......
...@@ -12,23 +12,36 @@ namespace content { ...@@ -12,23 +12,36 @@ namespace content {
namespace a11y { namespace a11y {
/** /**
* Converts cocoa node object to a line index in the formatted accessibility * Converts accessible node object to a line index in the formatted
* tree, the node is placed at, and vice versa. * accessibility tree, the node is placed at, and vice versa.
*/ */
class LineIndexesMap { class LineIndexer {
public: public:
LineIndexesMap(const BrowserAccessibilityCocoa* cocoa_node); LineIndexer();
~LineIndexesMap(); virtual ~LineIndexer();
std::string IndexBy(const BrowserAccessibilityCocoa* cocoa_node) const; std::string IndexBy(const gfx::NativeViewAccessible node) const;
gfx::NativeViewAccessible NodeBy(const std::string& index) const; gfx::NativeViewAccessible NodeBy(const std::string& index) const;
private: protected:
void Build(const BrowserAccessibilityCocoa* cocoa_node, int* counter); virtual NSArray* Children(const gfx::NativeViewAccessible node) const = 0;
void Build(const gfx::NativeViewAccessible node, int* counter);
private:
std::map<const gfx::NativeViewAccessible, std::string> map; std::map<const gfx::NativeViewAccessible, std::string> map;
}; };
/**
* Line indexer for internal BrowserAccessibilityCocoa trees.
*/
class CocoaLineIndexer final : public LineIndexer {
public:
CocoaLineIndexer(const BrowserAccessibilityCocoa* node);
protected:
NSArray* Children(const gfx::NativeViewAccessible node) const override;
};
// Implements stateful id values. Can be either id or be in // Implements stateful id values. Can be either id or be in
// error or not applciable state. Similar to base::Optional, but tri-state // error or not applciable state. Similar to base::Optional, but tri-state
// allowing nullable values. // allowing nullable values.
...@@ -64,7 +77,7 @@ class OptionalNSObject final { ...@@ -64,7 +77,7 @@ class OptionalNSObject final {
class AttributeInvoker final { class AttributeInvoker final {
public: public:
AttributeInvoker(const BrowserAccessibilityCocoa* cocoa_node, AttributeInvoker(const BrowserAccessibilityCocoa* cocoa_node,
const LineIndexesMap& line_indexes_map); const LineIndexer* line_indexer);
// Invokes an attribute matching to a property filter. // Invokes an attribute matching to a property filter.
OptionalNSObject Invoke(const PropertyNode& property_node) const; OptionalNSObject Invoke(const PropertyNode& property_node) const;
...@@ -86,7 +99,7 @@ class AttributeInvoker final { ...@@ -86,7 +99,7 @@ class AttributeInvoker final {
const base::string16 line_index) const; const base::string16 line_index) const;
const BrowserAccessibilityCocoa* cocoa_node; const BrowserAccessibilityCocoa* cocoa_node;
const LineIndexesMap& line_indexes_map; const LineIndexer* line_indexer;
const NSArray* attributes; const NSArray* attributes;
const NSArray* parameterized_attributes; const NSArray* parameterized_attributes;
}; };
......
...@@ -49,23 +49,18 @@ namespace { ...@@ -49,23 +49,18 @@ namespace {
} // namespace } // namespace
LineIndexesMap::LineIndexesMap(const BrowserAccessibilityCocoa* cocoa_node) { LineIndexer::LineIndexer() {}
int counter = 0; LineIndexer::~LineIndexer() {}
Build(cocoa_node, &counter);
}
LineIndexesMap::~LineIndexesMap() {} std::string LineIndexer::IndexBy(const gfx::NativeViewAccessible node) const {
std::string LineIndexesMap::IndexBy(
const BrowserAccessibilityCocoa* cocoa_node) const {
std::string line_index = ":unknown"; std::string line_index = ":unknown";
if (map.find(cocoa_node) != map.end()) { if (map.find(node) != map.end()) {
line_index = map.at(cocoa_node); line_index = map.at(node);
} }
return line_index; return line_index;
} }
gfx::NativeViewAccessible LineIndexesMap::NodeBy( gfx::NativeViewAccessible LineIndexer::NodeBy(
const std::string& line_index) const { const std::string& line_index) const {
for (std::pair<const gfx::NativeViewAccessible, std::string> item : map) { for (std::pair<const gfx::NativeViewAccessible, std::string> item : map) {
if (item.second == line_index) { if (item.second == line_index) {
...@@ -75,21 +70,30 @@ gfx::NativeViewAccessible LineIndexesMap::NodeBy( ...@@ -75,21 +70,30 @@ gfx::NativeViewAccessible LineIndexesMap::NodeBy(
return nil; return nil;
} }
void LineIndexesMap::Build(const BrowserAccessibilityCocoa* cocoa_node, void LineIndexer::Build(const gfx::NativeViewAccessible node, int* counter) {
int* counter) {
const std::string line_index = const std::string line_index =
std::string(1, ':') + base::NumberToString(++(*counter)); std::string(1, ':') + base::NumberToString(++(*counter));
map.insert({cocoa_node, line_index}); map.insert({node, line_index});
for (BrowserAccessibilityCocoa* cocoa_child in [cocoa_node children]) { NSArray* children = Children(node);
Build(cocoa_child, counter); for (gfx::NativeViewAccessible child in children) {
Build(child, counter);
} }
} }
CocoaLineIndexer::CocoaLineIndexer(const BrowserAccessibilityCocoa* node) {
int counter = 0;
Build(node, &counter);
}
NSArray* CocoaLineIndexer::Children(gfx::NativeViewAccessible node) const {
return [node children];
}
// AttributeInvoker // AttributeInvoker
AttributeInvoker::AttributeInvoker(const BrowserAccessibilityCocoa* cocoa_node, AttributeInvoker::AttributeInvoker(const BrowserAccessibilityCocoa* cocoa_node,
const LineIndexesMap& line_indexes_map) const LineIndexer* line_indexer)
: cocoa_node(cocoa_node), line_indexes_map(line_indexes_map) { : cocoa_node(cocoa_node), line_indexer(line_indexer) {
attributes = [cocoa_node accessibilityAttributeNames]; attributes = [cocoa_node accessibilityAttributeNames];
parameterized_attributes = parameterized_attributes =
[cocoa_node accessibilityParameterizedAttributeNames]; [cocoa_node accessibilityParameterizedAttributeNames];
...@@ -216,7 +220,7 @@ NSValue* AttributeInvoker::PropertyNodeToRange( ...@@ -216,7 +220,7 @@ NSValue* AttributeInvoker::PropertyNodeToRange(
gfx::NativeViewAccessible AttributeInvoker::PropertyNodeToUIElement( gfx::NativeViewAccessible AttributeInvoker::PropertyNodeToUIElement(
const PropertyNode& uielement_node) const { const PropertyNode& uielement_node) const {
gfx::NativeViewAccessible uielement = gfx::NativeViewAccessible uielement =
line_indexes_map.NodeBy(uielement_node.name_or_value); line_indexer->NodeBy(uielement_node.name_or_value);
if (!uielement) { if (!uielement) {
UIELEMENT_FAIL(uielement_node, UIELEMENT_FAIL(uielement_node,
"no corresponding UIElement was found in the tree") "no corresponding UIElement was found in the tree")
...@@ -233,7 +237,7 @@ id AttributeInvoker::DictNodeToTextMarker(const PropertyNode& dictnode) const { ...@@ -233,7 +237,7 @@ id AttributeInvoker::DictNodeToTextMarker(const PropertyNode& dictnode) const {
} }
BrowserAccessibilityCocoa* anchor_cocoa = BrowserAccessibilityCocoa* anchor_cocoa =
line_indexes_map.NodeBy(dictnode.parameters[0].name_or_value); line_indexer->NodeBy(dictnode.parameters[0].name_or_value);
if (!anchor_cocoa) { if (!anchor_cocoa) {
TEXTMARKER_FAIL(dictnode, "1st argument: wrong anchor") TEXTMARKER_FAIL(dictnode, "1st argument: wrong anchor")
} }
......
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