зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1618705: Construct column containers and list them as children of our table accessible. r=eeejay
Differential Revision: https://phabricator.services.mozilla.com/D67900 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
1407b0c42b
Коммит
945f2ee931
|
@ -1269,8 +1269,10 @@ struct RoleDescrComparator {
|
|||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
// make room for new children
|
||||
[mChildren release];
|
||||
mChildren = nil;
|
||||
if (mChildren) {
|
||||
[mChildren release];
|
||||
mChildren = nil;
|
||||
}
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
|
|
@ -7,15 +7,39 @@
|
|||
|
||||
#import "mozAccessible.h"
|
||||
|
||||
@interface mozColumnContainer : NSObject {
|
||||
uint32_t mIndex;
|
||||
mozAccessible* mParent;
|
||||
NSMutableArray* mChildren;
|
||||
}
|
||||
|
||||
- (id)initWithIndex:(uint32_t)aIndex andParent:(id<mozAccessible>)aParent;
|
||||
- (NSString*)accessibilityRole;
|
||||
- (NSString*)accessibilityRoleDescription;
|
||||
- (mozAccessible*)accessibilityParent;
|
||||
- (NSArray*)accessibilityChildren;
|
||||
- (BOOL)accessibilityIsIgnored;
|
||||
- (void)invalidateChildren;
|
||||
- (void)dealloc;
|
||||
- (void)expire;
|
||||
- (BOOL)isExpired;
|
||||
- (BOOL)accessibilityNotifiesWhenDestroyed;
|
||||
@end
|
||||
|
||||
@interface mozTablePartAccessible : mozAccessible
|
||||
- (id)accessibilityAttributeValue:(NSString*)attribute;
|
||||
- (BOOL)isLayoutTablePart;
|
||||
- (NSString*)role;
|
||||
@end
|
||||
|
||||
@interface mozTableAccessible : mozTablePartAccessible
|
||||
@interface mozTableAccessible : mozTablePartAccessible {
|
||||
NSMutableArray* mColContainers;
|
||||
}
|
||||
- (NSArray*)children;
|
||||
- (NSArray*)additionalAccessibilityAttributeNames;
|
||||
- (id)accessibilityAttributeValue:(NSString*)attribute;
|
||||
- (void)invalidateChildren;
|
||||
- (void)dealloc;
|
||||
@end
|
||||
|
||||
@interface mozTableRowAccessible : mozTablePartAccessible
|
||||
|
|
|
@ -7,6 +7,111 @@
|
|||
|
||||
#import "mozTableAccessible.h"
|
||||
#import "nsCocoaUtils.h"
|
||||
#import "AccIterator.h"
|
||||
#import "TableAccessible.h"
|
||||
|
||||
@implementation mozColumnContainer
|
||||
|
||||
- (id)initWithIndex:(uint32_t)aIndex andParent:(mozAccessible*)aParent {
|
||||
self = [super init];
|
||||
mIndex = aIndex;
|
||||
mParent = aParent;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSString*)accessibilityRole {
|
||||
return NSAccessibilityColumnRole;
|
||||
}
|
||||
|
||||
- (NSString*)accessibilityRoleDescription {
|
||||
return NSAccessibilityRoleDescription(NSAccessibilityColumnRole, nil);
|
||||
}
|
||||
|
||||
- (mozAccessible*)accessibilityParent {
|
||||
return mParent;
|
||||
}
|
||||
|
||||
- (NSArray*)accessibilityChildren {
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
if (mChildren) return mChildren;
|
||||
|
||||
mChildren = [[NSMutableArray alloc] init];
|
||||
|
||||
if (AccessibleWrap* accWrap = [mParent getGeckoAccessible]) {
|
||||
TableAccessible* table = accWrap->AsTable();
|
||||
NSAssert(table, @"Got null table when fetching column children!");
|
||||
uint32_t numRows = table->RowCount();
|
||||
|
||||
for (uint32_t j = 0; j < numRows; j++) {
|
||||
Accessible* cell = table->CellAt(j, mIndex);
|
||||
if (cell) {
|
||||
[mChildren addObject:GetNativeFromGeckoAccessible(cell)];
|
||||
}
|
||||
}
|
||||
|
||||
} else if (ProxyAccessible* proxy = [mParent getProxyAccessible]) {
|
||||
uint32_t numRows = proxy->TableRowCount();
|
||||
|
||||
for (uint32_t j = 0; j < numRows; j++) {
|
||||
ProxyAccessible* cell = proxy->TableCellAt(j, mIndex);
|
||||
if (cell) {
|
||||
[mChildren addObject:GetNativeFromProxy(cell)];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return mChildren;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
- (BOOL)accessibilityIsIgnored {
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void)invalidateChildren {
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
// make room for new children
|
||||
if (mChildren) {
|
||||
[mChildren release];
|
||||
mChildren = nil;
|
||||
}
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
[self invalidateChildren];
|
||||
[super dealloc];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
||||
- (void)expire {
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
[self invalidateChildren];
|
||||
|
||||
mParent = nil;
|
||||
|
||||
NSAccessibilityPostNotification(self, NSAccessibilityUIElementDestroyedNotification);
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
||||
- (BOOL)isExpired {
|
||||
return (mChildren == nil) && (mParent == nil);
|
||||
}
|
||||
|
||||
- (BOOL)accessibilityNotifiesWhenDestroyed {
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation mozTablePartAccessible
|
||||
|
||||
|
@ -50,6 +155,28 @@
|
|||
@end
|
||||
|
||||
@implementation mozTableAccessible
|
||||
|
||||
- (void)invalidateChildren {
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
if (mColContainers) {
|
||||
[mColContainers release];
|
||||
mColContainers = nil;
|
||||
}
|
||||
|
||||
[super invalidateChildren];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
[self invalidateChildren];
|
||||
[super dealloc];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
||||
- (NSArray*)additionalAccessibilityAttributeNames {
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
|
@ -64,6 +191,7 @@
|
|||
[tempArray addObject:NSAccessibilityRowCountAttribute];
|
||||
[tempArray addObject:NSAccessibilityColumnCountAttribute];
|
||||
[tempArray addObject:NSAccessibilityRowsAttribute];
|
||||
[tempArray addObject:NSAccessibilityColumnsAttribute];
|
||||
tableAttrs = [[NSArray alloc] initWithArray:tempArray];
|
||||
[tempArray release];
|
||||
}
|
||||
|
@ -91,6 +219,9 @@
|
|||
}
|
||||
return nativeArray;
|
||||
}
|
||||
if ([attribute isEqualToString:NSAccessibilityColumnsAttribute]) {
|
||||
return [self getColContainerList];
|
||||
}
|
||||
} else if (ProxyAccessible* proxy = [self getProxyAccessible]) {
|
||||
if ([attribute isEqualToString:NSAccessibilityRowCountAttribute])
|
||||
return @(proxy->TableRowCount());
|
||||
|
@ -108,10 +239,44 @@
|
|||
}
|
||||
return nativeArray;
|
||||
}
|
||||
if ([attribute isEqualToString:NSAccessibilityColumnsAttribute]) {
|
||||
return [self getColContainerList];
|
||||
}
|
||||
}
|
||||
|
||||
return [super accessibilityAttributeValue:attribute];
|
||||
}
|
||||
|
||||
- (NSArray*)children {
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
return [[super children] arrayByAddingObjectsFromArray:[self getColContainerList]];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
- (NSArray*)getColContainerList {
|
||||
if (mColContainers) {
|
||||
return mColContainers;
|
||||
}
|
||||
|
||||
mColContainers = [[NSMutableArray alloc] init];
|
||||
uint32_t numCols = 0;
|
||||
|
||||
if (AccessibleWrap* accWrap = [self getGeckoAccessible]) {
|
||||
numCols = accWrap->AsTable()->ColCount();
|
||||
} else if (ProxyAccessible* proxy = [self getProxyAccessible]) {
|
||||
numCols = proxy->TableColumnCount();
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < numCols; i++) {
|
||||
mozColumnContainer* container = [[mozColumnContainer alloc] initWithIndex:i andParent:self];
|
||||
[mColContainers addObject:container];
|
||||
}
|
||||
|
||||
return mColContainers;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation mozTableRowAccessible
|
||||
|
|
|
@ -14,5 +14,6 @@ support-files =
|
|||
[browser_details_summary.js]
|
||||
[browser_label_title.js]
|
||||
[browser_range.js]
|
||||
[browser_table.js]
|
||||
[browser_selectables.js]
|
||||
[browser_toggle_radio_check.js]
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
/* 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/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
/* import-globals-from ../../mochitest/role.js */
|
||||
|
||||
loadScripts({ name: "role.js", dir: MOCHITESTS_DIR });
|
||||
|
||||
/**
|
||||
* Test table, columns, rows
|
||||
*/
|
||||
addAccessibleTask(
|
||||
`<table id="customers">
|
||||
<tbody>
|
||||
<tr><th>Company</th><th>Contact</th><th>Country</th></tr>
|
||||
<tr><td>Alfreds Futterkiste</td><td>Maria Anders</td><td>Germany</td></tr>
|
||||
<tr><td>Centro comercial Moctezuma</td><td>Francisco Chang</td><td>Mexico</td></tr>
|
||||
<tr><td>Ernst Handel</td><td>Roland Mendel</td><td>Austria</td></tr>
|
||||
</tbody>
|
||||
</table>`,
|
||||
async (browser, accDoc) => {
|
||||
let table = getNativeInterface(accDoc, "customers");
|
||||
is(table.getAttributeValue("AXRole"), "AXTable", "Correct role for table");
|
||||
|
||||
let tableChildren = table.getAttributeValue("AXChildren");
|
||||
// XXX: Should be 8 children, rows (incl headers) + cols + headers
|
||||
// if we're trying to match Safari.
|
||||
is(tableChildren.length, 7, "Table has children = rows (4) + cols (3)");
|
||||
for (let i = 0; i < tableChildren.length; i++) {
|
||||
let currChild = tableChildren[i];
|
||||
if (i < 4) {
|
||||
is(
|
||||
currChild.getAttributeValue("AXRole"),
|
||||
"AXRow",
|
||||
"Correct role for row"
|
||||
);
|
||||
} else {
|
||||
is(
|
||||
currChild.getAttributeValue("AXRole"),
|
||||
"AXColumn",
|
||||
"Correct role for col"
|
||||
);
|
||||
is(
|
||||
currChild.getAttributeValue("AXRoleDescription"),
|
||||
"column",
|
||||
"Correct role desc for col"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
is(
|
||||
table.getAttributeValue("AXColumnCount"),
|
||||
3,
|
||||
"Table has correct column count."
|
||||
);
|
||||
is(
|
||||
table.getAttributeValue("AXRowCount"),
|
||||
4,
|
||||
"Table has correct row count."
|
||||
);
|
||||
|
||||
let cols = table.getAttributeValue("AXColumns");
|
||||
is(cols.length, 3, "Table has col list of correct length");
|
||||
for (let i = 0; i < cols.length; i++) {
|
||||
let currCol = cols[i];
|
||||
let currChildren = currCol.getAttributeValue("AXChildren");
|
||||
is(currChildren.length, 4, "Column has correct number of cells");
|
||||
for (let j = 0; j < currChildren.length; j++) {
|
||||
let currChild = currChildren[j];
|
||||
is(
|
||||
currChild.getAttributeValue("AXRole"),
|
||||
"AXCell",
|
||||
"Column child is cell"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
let rows = table.getAttributeValue("AXRows");
|
||||
is(rows.length, 4, "Table has row list of correct length");
|
||||
for (let i = 0; i < rows.length; i++) {
|
||||
let currRow = rows[i];
|
||||
let currChildren = currRow.getAttributeValue("AXChildren");
|
||||
is(currChildren.length, 3, "Row has correct number of cells");
|
||||
for (let j = 0; j < currChildren.length; j++) {
|
||||
let currChild = currChildren[j];
|
||||
is(
|
||||
currChild.getAttributeValue("AXRole"),
|
||||
"AXCell",
|
||||
"Row child is cell"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
|
@ -341,7 +341,9 @@ nsresult xpcAccessibleMacInterface::NSObjectToJsValue(id aObj, JSContext* aCx,
|
|||
return NSObjectToJsValue(
|
||||
@[ [NSNumber numberWithDouble:size.width], [NSNumber numberWithDouble:size.height] ], aCx,
|
||||
aResult);
|
||||
} else if ([aObj respondsToSelector:@selector(accessibilityAttributeNames)]) {
|
||||
} else if ([aObj respondsToSelector:@selector(accessibilityIsIgnored)]) {
|
||||
// We expect all of our accessibility objects to implement accessibilityIsIgnored
|
||||
// at the very least. If it is implemented we will assume its an accessibility object.
|
||||
nsCOMPtr<nsIAccessibleMacInterface> obj = new xpcAccessibleMacInterface(aObj);
|
||||
return nsContentUtils::WrapNative(aCx, obj, &NS_GET_IID(nsIAccessibleMacInterface), aResult);
|
||||
} else if ([aObj isKindOfClass:[NSArray class]]) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче