summaryrefslogtreecommitdiff
path: root/accessible/mac/mozTableAccessible.mm
diff options
context:
space:
mode:
Diffstat (limited to 'accessible/mac/mozTableAccessible.mm')
-rw-r--r--accessible/mac/mozTableAccessible.mm281
1 files changed, 281 insertions, 0 deletions
diff --git a/accessible/mac/mozTableAccessible.mm b/accessible/mac/mozTableAccessible.mm
new file mode 100644
index 0000000000..6ad157b9f0
--- /dev/null
+++ b/accessible/mac/mozTableAccessible.mm
@@ -0,0 +1,281 @@
+/* -*- Mode: Objective-C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:expandtab:shiftwidth=2:tabstop=2:
+ */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#import "Accessible-inl.h"
+#import "mozTableAccessible.h"
+#import "TableAccessible.h"
+#import "TableCellAccessible.h"
+#import "nsCocoaUtils.h"
+
+using namespace mozilla::a11y;
+
+// 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.
+ size_t totalCount = aArray.Length();
+ for (size_t i = 0; i < totalCount; i++) {
+ Accessible* curAccessible = aArray.ElementAt(i);
+ mozAccessible* curNative = GetNativeFromGeckoAccessible(curAccessible);
+ if (curNative)
+ [nativeArray addObject:GetObjectOrRepresentedView(curNative)];
+ }
+
+ return nativeArray;
+}
+
+// convert an array of Gecko proxy accessibles to an NSArray of native accessibles
+static inline NSMutableArray*
+ConvertToNSArray(nsTArray<ProxyAccessible*>& aArray)
+{
+ NSMutableArray* nativeArray = [[NSMutableArray alloc] init];
+
+ // iterate through the list, and get each native accessible.
+ size_t totalCount = aArray.Length();
+ for (size_t i = 0; i < totalCount; i++) {
+ ProxyAccessible* curAccessible = aArray.ElementAt(i);
+ mozAccessible* curNative = GetNativeFromProxy(curAccessible);
+ if (curNative)
+ [nativeArray addObject:GetObjectOrRepresentedView(curNative)];
+ }
+
+ return nativeArray;
+}
+
+@implementation mozTablePartAccessible
+- (BOOL)isLayoutTablePart;
+{
+ if (Accessible* accWrap = [self getGeckoAccessible]) {
+ while (accWrap) {
+ if (accWrap->IsTable()) {
+ return accWrap->AsTable()->IsProbablyLayoutTable();
+ }
+ accWrap = accWrap->Parent();
+ }
+ return false;
+ }
+
+ if (ProxyAccessible* proxy = [self getProxyAccessible]) {
+ while (proxy) {
+ if (proxy->IsTable()) {
+ return proxy->TableIsProbablyForLayout();
+ }
+ proxy = proxy->Parent();
+ }
+ }
+
+ return false;
+}
+
+- (NSString*)role
+{
+ return [self isLayoutTablePart] ? NSAccessibilityGroupRole : [super role];
+}
+@end
+
+@implementation mozTableAccessible
+- (NSArray*)additionalAccessibilityAttributeNames
+{
+ NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
+
+ NSArray* additionalAttributes = [super additionalAccessibilityAttributeNames];
+ if ([self isLayoutTablePart]) {
+ return additionalAttributes;
+ }
+
+ static NSArray* tableAttrs = nil;
+ if (!tableAttrs) {
+ NSMutableArray* tempArray = [NSMutableArray new];
+ [tempArray addObject:NSAccessibilityRowCountAttribute];
+ [tempArray addObject:NSAccessibilityColumnCountAttribute];
+ [tempArray addObject:NSAccessibilityRowsAttribute];
+ tableAttrs = [[NSArray alloc] initWithArray:tempArray];
+ [tempArray release];
+ }
+
+ return [additionalAttributes arrayByAddingObjectsFromArray:tableAttrs];
+
+ NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
+}
+
+- (id)accessibilityAttributeValue:(NSString*)attribute
+{
+ if (AccessibleWrap* accWrap = [self getGeckoAccessible]) {
+ 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 (ProxyAccessible* proxy = [self getProxyAccessible]) {
+ if ([attribute isEqualToString:NSAccessibilityRowCountAttribute])
+ return @(proxy->TableRowCount());
+ if ([attribute isEqualToString:NSAccessibilityColumnCountAttribute])
+ return @(proxy->TableColumnCount());
+ if ([attribute isEqualToString:NSAccessibilityRowsAttribute]) {
+ // Create a new array with the list of table rows.
+ NSMutableArray* nativeArray = [[NSMutableArray alloc] init];
+ uint32_t totalCount = proxy->ChildrenCount();
+ for (uint32_t i = 0; i < totalCount; i++) {
+ if (proxy->ChildAt(i)->IsTableRow()) {
+ mozAccessible* curNative =
+ GetNativeFromProxy(proxy->ChildAt(i));
+ if (curNative)
+ [nativeArray addObject:GetObjectOrRepresentedView(curNative)];
+ }
+ }
+ return nativeArray;
+ }
+ }
+
+ return [super accessibilityAttributeValue:attribute];
+}
+@end
+
+@implementation mozTableRowAccessible
+- (NSArray*)additionalAccessibilityAttributeNames
+{
+ NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
+
+ NSArray* additionalAttributes = [super additionalAccessibilityAttributeNames];
+ if ([self isLayoutTablePart]) {
+ return additionalAttributes;
+ }
+
+ static NSArray* tableRowAttrs = nil;
+ if (!tableRowAttrs) {
+ NSMutableArray* tempArray = [NSMutableArray new];
+ [tempArray addObject:NSAccessibilityIndexAttribute];
+ tableRowAttrs = [[NSArray alloc] initWithArray:tempArray];
+ [tempArray release];
+ }
+
+ return [additionalAttributes arrayByAddingObjectsFromArray:tableRowAttrs];
+
+ NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
+}
+
+- (id)accessibilityAttributeValue:(NSString*)attribute
+{
+ if (AccessibleWrap* accWrap = [self getGeckoAccessible]) {
+ if ([attribute isEqualToString:NSAccessibilityIndexAttribute]) {
+ // Count the number of rows before that one to obtain the row index.
+ uint32_t index = 0;
+ Accessible* parent = accWrap->Parent();
+ if (parent) {
+ for (int32_t i = accWrap->IndexInParent() - 1; i >= 0; i--) {
+ if (parent->GetChildAt(i)->IsTableRow()) {
+ index++;
+ }
+ }
+ }
+ return [NSNumber numberWithUnsignedInteger:index];
+ }
+ } else if (ProxyAccessible* proxy = [self getProxyAccessible]) {
+ if ([attribute isEqualToString:NSAccessibilityIndexAttribute]) {
+ // Count the number of rows before that one to obtain the row index.
+ uint32_t index = 0;
+ ProxyAccessible* parent = proxy->Parent();
+ if (parent) {
+ for (int32_t i = proxy->IndexInParent() - 1; i >= 0; i--) {
+ if (parent->ChildAt(i)->IsTableRow()) {
+ index++;
+ }
+ }
+ }
+ return [NSNumber numberWithUnsignedInteger:index];
+ }
+ }
+
+ return [super accessibilityAttributeValue:attribute];
+}
+@end
+
+@implementation mozTableCellAccessible
+- (NSArray*)additionalAccessibilityAttributeNames
+{
+ NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
+
+ NSArray* additionalAttributes = [super additionalAccessibilityAttributeNames];
+ if ([self isLayoutTablePart]) {
+ return additionalAttributes;
+ }
+
+ static NSArray* tableCellAttrs = nil;
+ if (!tableCellAttrs) {
+ NSMutableArray* tempArray = [NSMutableArray new];
+ [tempArray addObject:NSAccessibilityRowIndexRangeAttribute];
+ [tempArray addObject:NSAccessibilityColumnIndexRangeAttribute];
+ [tempArray addObject:NSAccessibilityRowHeaderUIElementsAttribute];
+ [tempArray addObject:NSAccessibilityColumnHeaderUIElementsAttribute];
+ tableCellAttrs = [[NSArray alloc] initWithArray:tempArray];
+ [tempArray release];
+ }
+
+ return [additionalAttributes arrayByAddingObjectsFromArray:tableCellAttrs];
+
+ NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
+}
+
+- (id)accessibilityAttributeValue:(NSString*)attribute
+{
+ if (AccessibleWrap* accWrap = [self getGeckoAccessible]) {
+ 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]) {
+ AutoTArray<Accessible*, 10> headerCells;
+ cell->RowHeaderCells(&headerCells);
+ return ConvertToNSArray(headerCells);
+ }
+ if ([attribute isEqualToString:NSAccessibilityColumnHeaderUIElementsAttribute]) {
+ AutoTArray<Accessible*, 10> headerCells;
+ cell->ColHeaderCells(&headerCells);
+ return ConvertToNSArray(headerCells);
+ }
+ } else if (ProxyAccessible* proxy = [self getProxyAccessible]) {
+ if ([attribute isEqualToString:NSAccessibilityRowIndexRangeAttribute])
+ return [NSValue valueWithRange:NSMakeRange(proxy->RowIdx(),
+ proxy->RowExtent())];
+ if ([attribute isEqualToString:NSAccessibilityColumnIndexRangeAttribute])
+ return [NSValue valueWithRange:NSMakeRange(proxy->ColIdx(),
+ proxy->ColExtent())];
+ if ([attribute isEqualToString:NSAccessibilityRowHeaderUIElementsAttribute]) {
+ nsTArray<ProxyAccessible*> headerCells;
+ proxy->RowHeaderCells(&headerCells);
+ return ConvertToNSArray(headerCells);
+ }
+ if ([attribute isEqualToString:NSAccessibilityColumnHeaderUIElementsAttribute]) {
+ nsTArray<ProxyAccessible*> headerCells;
+ proxy->ColHeaderCells(&headerCells);
+ return ConvertToNSArray(headerCells);
+ }
+ }
+
+ return [super accessibilityAttributeValue:attribute];
+}
+@end