Bug 744790 - Expose basic NSAccessibility attributes for tables. r=surkov

This commit is contained in:
Frédéric Wang 2015-06-25 21:51:00 +02:00
parent 0c2b7f3dff
commit 3f44140e1b

View File

@ -16,6 +16,8 @@
#include "Relation.h"
#include "Role.h"
#include "RootAccessible.h"
#include "TableAccessible.h"
#include "TableCellAccessible.h"
#include "mozilla/Services.h"
#include "nsRect.h"
@ -73,6 +75,24 @@ GetClosestInterestingAccessible(id anObject)
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
}
// convert an array of Gecko accessibles to an NSArray of native accessibles
static inline NSMutableArray*
ConvertToNSArray(nsTArray<Accessible*>& aArray)
{
NSMutableArray* nativeArray = [[NSMutableArray alloc] init];
// iterate through the list, and get each native accessible.
uint32_t totalCount = aArray.Length();
for (uint32_t i = 0; i < totalCount; i++) {
Accessible* curAccessible = aArray.ElementAt(i);
mozAccessible* curNative = GetNativeFromGeckoAccessible(curAccessible);
if (curNative)
[nativeArray addObject:GetObjectOrRepresentedView(curNative)];
}
return nativeArray;
}
#pragma mark -
@implementation mozAccessible
@ -189,10 +209,15 @@ GetClosestInterestingAccessible(id anObject)
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
// if we're expired, we don't support any attributes.
if (![self getGeckoAccessible])
AccessibleWrap* accWrap = [self getGeckoAccessible];
if (!accWrap)
return [NSArray array];
static NSArray *generalAttributes = nil;
static NSArray* generalAttributes = nil;
static NSArray* tableAttrs = nil;
static NSArray* tableRowAttrs = nil;
static NSArray* tableCellAttrs = nil;
NSMutableArray* tempArray = nil;
if (!generalAttributes) {
// standard attributes that are shared and supported by all generic elements.
@ -218,7 +243,39 @@ GetClosestInterestingAccessible(id anObject)
nil];
}
if (!tableAttrs) {
tempArray = [[NSMutableArray alloc] initWithArray:generalAttributes];
[tempArray addObject:NSAccessibilityRowCountAttribute];
[tempArray addObject:NSAccessibilityColumnCountAttribute];
[tempArray addObject:NSAccessibilityRowsAttribute];
tableAttrs = [[NSArray alloc] initWithArray:tempArray];
[tempArray release];
}
if (!tableRowAttrs) {
tempArray = [[NSMutableArray alloc] initWithArray:generalAttributes];
[tempArray addObject:NSAccessibilityIndexAttribute];
tableRowAttrs = [[NSArray alloc] initWithArray:tempArray];
[tempArray release];
}
if (!tableCellAttrs) {
tempArray = [[NSMutableArray alloc] initWithArray:generalAttributes];
[tempArray addObject:NSAccessibilityRowIndexRangeAttribute];
[tempArray addObject:NSAccessibilityColumnIndexRangeAttribute];
[tempArray addObject:NSAccessibilityRowHeaderUIElementsAttribute];
[tempArray addObject:NSAccessibilityColumnHeaderUIElementsAttribute];
tableCellAttrs = [[NSArray alloc] initWithArray:tempArray];
[tempArray release];
}
NSArray* objectAttributes = generalAttributes;
if (accWrap->IsTable())
objectAttributes = tableAttrs;
else if (accWrap->IsTableRow())
objectAttributes = tableRowAttrs;
else if (accWrap->IsTableCell())
objectAttributes = tableCellAttrs;
NSArray* additionalAttributes = [self additionalAccessibilityAttributeNames];
if ([additionalAttributes count])
objectAttributes = [objectAttributes arrayByAddingObjectsFromArray:additionalAttributes];
@ -247,7 +304,8 @@ GetClosestInterestingAccessible(id anObject)
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
if (![self getGeckoAccessible])
AccessibleWrap* accWrap = [self getGeckoAccessible];
if (!accWrap)
return nil;
#if DEBUG
@ -290,13 +348,64 @@ GetClosestInterestingAccessible(id anObject)
return [self title];
if ([attribute isEqualToString:NSAccessibilityTitleUIElementAttribute]) {
Relation rel =
[self getGeckoAccessible]->RelationByType(RelationType::LABELLED_BY);
accWrap->RelationByType(RelationType::LABELLED_BY);
Accessible* tempAcc = rel.Next();
return tempAcc ? GetNativeFromGeckoAccessible(tempAcc) : nil;
}
if ([attribute isEqualToString:NSAccessibilityHelpAttribute])
return [self help];
if (accWrap->IsTable()) {
TableAccessible* table = accWrap->AsTable();
if ([attribute isEqualToString:NSAccessibilityRowCountAttribute])
return @(table->RowCount());
if ([attribute isEqualToString:NSAccessibilityColumnCountAttribute])
return @(table->ColCount());
if ([attribute isEqualToString:NSAccessibilityRowsAttribute]) {
// Create a new array with the list of table rows.
NSMutableArray* nativeArray = [[NSMutableArray alloc] init];
uint32_t totalCount = accWrap->ChildCount();
for (uint32_t i = 0; i < totalCount; i++) {
if (accWrap->GetChildAt(i)->IsTableRow()) {
mozAccessible* curNative =
GetNativeFromGeckoAccessible(accWrap->GetChildAt(i));
if (curNative)
[nativeArray addObject:GetObjectOrRepresentedView(curNative)];
}
}
return nativeArray;
}
} else if (accWrap->IsTableRow()) {
if ([attribute isEqualToString:NSAccessibilityIndexAttribute]) {
// Count the number of rows before that one to obtain the row index.
uint32_t index = 0;
for (int32_t i = accWrap->IndexInParent() - 1; i >= 0; i--) {
if (accWrap->GetChildAt(i)->IsTableRow()) {
index++;
}
}
return [NSNumber numberWithUnsignedInteger:index];
}
} else if (accWrap->IsTableCell()) {
TableCellAccessible* cell = accWrap->AsTableCell();
if ([attribute isEqualToString:NSAccessibilityRowIndexRangeAttribute])
return [NSValue valueWithRange:NSMakeRange(cell->RowIdx(),
cell->RowExtent())];
if ([attribute isEqualToString:NSAccessibilityColumnIndexRangeAttribute])
return [NSValue valueWithRange:NSMakeRange(cell->ColIdx(),
cell->ColExtent())];
if ([attribute isEqualToString:NSAccessibilityRowHeaderUIElementsAttribute]) {
nsAutoTArray<Accessible*, 10> headerCells;
cell->RowHeaderCells(&headerCells);
return ConvertToNSArray(headerCells);
}
if ([attribute isEqualToString:NSAccessibilityColumnHeaderUIElementsAttribute]) {
nsAutoTArray<Accessible*, 10> headerCells;
cell->ColHeaderCells(&headerCells);
return ConvertToNSArray(headerCells);
}
}
switch (mRole) {
case roles::MATHML_ROOT:
if ([attribute isEqualToString:NSAccessibilityMathRootRadicandAttribute])
@ -534,22 +643,10 @@ GetClosestInterestingAccessible(id anObject)
if (mChildren || !accWrap->AreChildrenCached())
return mChildren;
mChildren = [[NSMutableArray alloc] init];
// get the array of children.
nsAutoTArray<Accessible*, 10> childrenArray;
accWrap->GetUnignoredChildren(&childrenArray);
// now iterate through the children array, and get each native accessible.
uint32_t totalCount = childrenArray.Length();
for (uint32_t idx = 0; idx < totalCount; idx++) {
Accessible* curAccessible = childrenArray.ElementAt(idx);
if (curAccessible) {
mozAccessible *curNative = GetNativeFromGeckoAccessible(curAccessible);
if (curNative)
[mChildren addObject:GetObjectOrRepresentedView(curNative)];
}
}
mChildren = ConvertToNSArray(childrenArray);
#ifdef DEBUG_hakan
// make sure we're not returning any ignored accessibles.