Bug 1625953 - P1: Introduce getRelationsByType for mozAccessible. r=morgan

A small refactor to make all of the relations getting easier.

Differential Revision: https://phabricator.services.mozilla.com/D101084
This commit is contained in:
Eitan Isaacson 2021-01-08 00:19:04 +00:00
Родитель 07863cc5ea
Коммит 1dcdfb0a26
6 изменённых файлов: 42 добавлений и 79 удалений

Просмотреть файл

@ -11,17 +11,18 @@
#include "nsStringFwd.h" #include "nsStringFwd.h"
@class NSString; @class NSString;
@class mozAccessible;
namespace mozilla { namespace mozilla {
namespace a11y { namespace a11y {
namespace utils { namespace utils {
// convert an array of Gecko accessibles to an NSArray of native accessibles // convert an array of Gecko accessibles to an NSArray of native accessibles
NSMutableArray* ConvertToNSArray(nsTArray<Accessible*>& aArray); NSArray<mozAccessible*>* ConvertToNSArray(nsTArray<Accessible*>& aArray);
// convert an array of Gecko proxy accessibles to an NSArray of native // convert an array of Gecko proxy accessibles to an NSArray of native
// accessibles // accessibles
NSMutableArray* ConvertToNSArray(nsTArray<ProxyAccessible*>& aArray); NSArray<mozAccessible*>* ConvertToNSArray(nsTArray<ProxyAccessible*>& aArray);
/** /**
* Get a localized string from the string bundle. * Get a localized string from the string bundle.

Просмотреть файл

@ -17,7 +17,7 @@ namespace a11y {
namespace utils { namespace utils {
// convert an array of Gecko accessibles to an NSArray of native accessibles // convert an array of Gecko accessibles to an NSArray of native accessibles
NSMutableArray* ConvertToNSArray(nsTArray<Accessible*>& aArray) { NSArray<mozAccessible*>* ConvertToNSArray(nsTArray<Accessible*>& aArray) {
NSMutableArray* nativeArray = [[NSMutableArray alloc] init]; NSMutableArray* nativeArray = [[NSMutableArray alloc] init];
// iterate through the list, and get each native accessible. // iterate through the list, and get each native accessible.
@ -34,7 +34,7 @@ NSMutableArray* ConvertToNSArray(nsTArray<Accessible*>& aArray) {
// convert an array of Gecko proxy accessibles to an NSArray of native // convert an array of Gecko proxy accessibles to an NSArray of native
// accessibles // accessibles
NSMutableArray* ConvertToNSArray(nsTArray<ProxyAccessible*>& aArray) { NSArray<mozAccessible*>* ConvertToNSArray(nsTArray<ProxyAccessible*>& aArray) {
NSMutableArray* nativeArray = [[NSMutableArray alloc] init]; NSMutableArray* nativeArray = [[NSMutableArray alloc] init];
// iterate through the list, and get each native accessible. // iterate through the list, and get each native accessible.

Просмотреть файл

@ -114,6 +114,10 @@ inline mozAccessible* GetNativeFromGeckoAccessible(
// Get ARIA role // Get ARIA role
- (nsStaticAtom*)ARIARole; - (nsStaticAtom*)ARIARole;
// Get array of related mozAccessibles
- (NSArray<mozAccessible*>*)getRelationsByType:
(mozilla::a11y::RelationType)relationType;
#pragma mark - mozAccessible protocol / widget #pragma mark - mozAccessible protocol / widget
// override // override

Просмотреть файл

@ -598,25 +598,17 @@ struct RoleDescrComparator {
if (flag == eNameFromSubtree) { if (flag == eNameFromSubtree) {
return nil; return nil;
} }
if (![self providesLabelNotTitle]) {
Relation rel = acc->RelationByType(RelationType::LABELLED_BY);
if (rel.Next() && !rel.Next()) {
return nil;
}
}
} else if (proxy) { } else if (proxy) {
uint32_t flag = proxy->Name(name); uint32_t flag = proxy->Name(name);
if (flag == eNameFromSubtree) { if (flag == eNameFromSubtree) {
return nil; return nil;
} }
}
if (![self providesLabelNotTitle]) { if (![self providesLabelNotTitle]) {
nsTArray<ProxyAccessible*> rels = NSArray* relations = [self getRelationsByType:RelationType::LABELLED_BY];
proxy->RelationByType(RelationType::LABELLED_BY); if ([relations count] == 1) {
if (rels.Length() == 1) { return nil;
return nil;
}
} }
} }
@ -748,24 +740,9 @@ struct RoleDescrComparator {
- (id)moxTitleUIElement { - (id)moxTitleUIElement {
MOZ_ASSERT(!mGeckoAccessible.IsNull()); MOZ_ASSERT(!mGeckoAccessible.IsNull());
if (Accessible* acc = mGeckoAccessible.AsAccessible()) { NSArray* relations = [self getRelationsByType:RelationType::LABELLED_BY];
Relation rel = acc->RelationByType(RelationType::LABELLED_BY); if ([relations count] == 1) {
Accessible* tempAcc = rel.Next(); return [relations firstObject];
if (tempAcc && !rel.Next()) {
mozAccessible* label = GetNativeFromGeckoAccessible(tempAcc);
return [label isAccessibilityElement] ? label : nil;
}
return nil;
}
ProxyAccessible* proxy = mGeckoAccessible.AsProxy();
nsTArray<ProxyAccessible*> rel =
proxy->RelationByType(RelationType::LABELLED_BY);
ProxyAccessible* tempProxy = rel.SafeElementAt(0);
if (tempProxy && rel.Length() <= 1) {
mozAccessible* label = GetNativeFromGeckoAccessible(tempProxy);
return [label isAccessibilityElement] ? label : nil;
} }
return nil; return nil;
@ -986,6 +963,24 @@ struct RoleDescrComparator {
} }
} }
- (NSArray<mozAccessible*>*)getRelationsByType:(RelationType)relationType {
if (Accessible* acc = mGeckoAccessible.AsAccessible()) {
NSMutableArray<mozAccessible*>* relations = [[NSMutableArray alloc] init];
Relation rel = acc->RelationByType(relationType);
while (Accessible* relAcc = rel.Next()) {
if (mozAccessible* relNative = GetNativeFromGeckoAccessible(relAcc)) {
[relations addObject:relNative];
}
}
return relations;
}
ProxyAccessible* proxy = mGeckoAccessible.AsProxy();
nsTArray<ProxyAccessible*> rel = proxy->RelationByType(relationType);
return utils::ConvertToNSArray(rel);
}
- (void)handleAccessibleTextChangeEvent:(NSString*)change - (void)handleAccessibleTextChangeEvent:(NSString*)change
inserted:(BOOL)isInserted inserted:(BOOL)isInserted
inContainer:(const AccessibleOrProxy&)container inContainer:(const AccessibleOrProxy&)container

Просмотреть файл

@ -88,21 +88,7 @@ enum CheckboxValue {
} }
if ([attribute isEqualToString:NSAccessibilityLinkedUIElementsAttribute]) { if ([attribute isEqualToString:NSAccessibilityLinkedUIElementsAttribute]) {
if (HTMLRadioButtonAccessible* radioAcc = return [self getRelationsByType:RelationType::MEMBER_OF];
(HTMLRadioButtonAccessible*)mGeckoAccessible.AsAccessible()) {
NSMutableArray* radioSiblings = [NSMutableArray new];
Relation rel = radioAcc->RelationByType(RelationType::MEMBER_OF);
Accessible* tempAcc;
while ((tempAcc = rel.Next())) {
[radioSiblings addObject:GetNativeFromGeckoAccessible(tempAcc)];
}
return radioSiblings;
} else {
ProxyAccessible* proxy = mGeckoAccessible.AsProxy();
nsTArray<ProxyAccessible*> accs =
proxy->RelationByType(RelationType::MEMBER_OF);
return utils::ConvertToNSArray(accs);
}
} }
return [super accessibilityAttributeValue:attribute]; return [super accessibilityAttributeValue:attribute];

Просмотреть файл

@ -481,21 +481,11 @@ using namespace mozilla::a11y;
// all rows are direct children of the outline; they use // all rows are direct children of the outline; they use
// relations to expose their heirarchy structure. // relations to expose their heirarchy structure.
mozAccessible* disclosingRow = nil;
// first we check the relations to see if we're in a xul tree // first we check the relations to see if we're in a xul tree
// with weird row semantics // with weird row semantics
if (mGeckoAccessible.IsAccessible()) { NSArray<mozAccessible*>* disclosingRows =
Relation rel = mGeckoAccessible.AsAccessible()->RelationByType( [self getRelationsByType:RelationType::NODE_CHILD_OF];
RelationType::NODE_CHILD_OF); mozAccessible* disclosingRow = [disclosingRows firstObject];
Accessible* maybeParent = rel.Next();
disclosingRow =
maybeParent ? GetNativeFromGeckoAccessible(maybeParent) : nil;
} else {
nsTArray<ProxyAccessible*> accs =
mGeckoAccessible.AsProxy()->RelationByType(RelationType::NODE_CHILD_OF);
disclosingRow =
accs.Length() > 0 ? GetNativeFromGeckoAccessible(accs[0]) : nil;
}
if (disclosingRow) { if (disclosingRow) {
// if we find a row from our relation check, // if we find a row from our relation check,
@ -507,6 +497,7 @@ using namespace mozilla::a11y;
return disclosingRow; return disclosingRow;
} }
mozAccessible* parent = (mozAccessible*)[self moxUnignoredParent]; mozAccessible* parent = (mozAccessible*)[self moxUnignoredParent];
// otherwise, its likely we're in an aria tree, so we can use // otherwise, its likely we're in an aria tree, so we can use
// these role and subrole checks // these role and subrole checks
@ -539,24 +530,10 @@ using namespace mozilla::a11y;
// xul trees so we have to use relations first and then fall-back // xul trees so we have to use relations first and then fall-back
// to the children filter for non-xul outlines. // to the children filter for non-xul outlines.
NSMutableArray* disclosedRows = [[NSMutableArray alloc] init];
// first we check the relations to see if we're in a xul tree // first we check the relations to see if we're in a xul tree
// with weird row semantics // with weird row semantics
if (mGeckoAccessible.IsAccessible()) { if (NSArray* disclosedRows =
Relation rel = mGeckoAccessible.AsAccessible()->RelationByType( [self getRelationsByType:RelationType::NODE_PARENT_OF]) {
RelationType::NODE_PARENT_OF);
Accessible* acc = nullptr;
while ((acc = rel.Next())) {
[disclosedRows addObject:GetNativeFromGeckoAccessible(acc)];
}
} else {
nsTArray<ProxyAccessible*> accs =
mGeckoAccessible.AsProxy()->RelationByType(
RelationType::NODE_PARENT_OF);
disclosedRows = utils::ConvertToNSArray(accs);
}
if (disclosedRows) {
// if we find rows from our relation check, return them here // if we find rows from our relation check, return them here
return disclosedRows; return disclosedRows;
} }