Bug 1668101: Support same/different type naviagation with VO r=eeejay

Differential Revision: https://phabricator.services.mozilla.com/D91833
This commit is contained in:
Morgan Reschenberg 2020-10-15 16:42:14 +00:00
Родитель b094c1a9c6
Коммит c5ff480218
4 изменённых файлов: 121 добавлений и 1 удалений

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

@ -113,6 +113,7 @@ using namespace mozilla::a11y;
- (NSArray*)performSearch {
AccessibleOrProxy geckoRootAcc = [self rootGeckoAccessible];
AccessibleOrProxy geckoStartAcc = [self startGeckoAccessible];
NSMutableArray* matches = [[NSMutableArray alloc] init];
for (id key in mSearchKeys) {
if ([key isEqualToString:@"AXAnyTypeSearchKey"]) {
@ -218,6 +219,24 @@ using namespace mozilla::a11y;
[matches addObjectsFromArray:[self getMatchesForRule:rule]];
}
if ([key isEqualToString:@"AXSameTypeSearchKey"]) {
mozAccessible* native = GetNativeFromGeckoAccessible(geckoStartAcc);
NSString* macRole = [native moxRole];
RotorMacRoleRule rule = mImmediateDescendantsOnly
? RotorMacRoleRule(macRole, geckoRootAcc)
: RotorMacRoleRule(macRole);
[matches addObjectsFromArray:[self getMatchesForRule:rule]];
}
if ([key isEqualToString:@"AXDifferentTypeSearchKey"]) {
mozAccessible* native = GetNativeFromGeckoAccessible(geckoStartAcc);
NSString* macRole = [native moxRole];
RotorNotMacRoleRule rule =
mImmediateDescendantsOnly ? RotorNotMacRoleRule(macRole, geckoRootAcc)
: RotorNotMacRoleRule(macRole);
[matches addObjectsFromArray:[self getMatchesForRule:rule]];
}
if ([key isEqualToString:@"AXRadioGroupSearchKey"]) {
RotorRoleRule rule = mImmediateDescendantsOnly
? RotorRoleRule(roles::RADIO_GROUP, geckoRootAcc)

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

@ -45,7 +45,7 @@ class RotorMacRoleRule : public RotorRule {
~RotorMacRoleRule();
virtual uint16_t Match(const AccessibleOrProxy& aAccOrProxy) override;
private:
protected:
NSString* mMacRole;
};
@ -81,6 +81,18 @@ class RotorUnvisitedLinkRule final : public RotorLinkRule {
virtual uint16_t Match(const AccessibleOrProxy& aAccOrProxy) override;
};
/**
* This rule matches all accessibles that satisfy the "boilerplate"
* pivot conditions and have a corresponding native accessible.
*/
class RotorNotMacRoleRule : public RotorMacRoleRule {
public:
explicit RotorNotMacRoleRule(NSString* aMacRole,
AccessibleOrProxy& aDirectDescendantsFrom);
explicit RotorNotMacRoleRule(NSString* aMacRole);
uint16_t Match(const AccessibleOrProxy& aAccOrProxy) override;
};
class RotorStaticTextRule : public RotorRule {
public:
explicit RotorStaticTextRule();

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

@ -226,6 +226,31 @@ uint16_t RotorUnvisitedLinkRule::Match(const AccessibleOrProxy& aAccOrProxy) {
return result;
}
// Match Not Rule
RotorNotMacRoleRule::RotorNotMacRoleRule(
NSString* aMacRole, AccessibleOrProxy& aDirectDescendantsFrom)
: RotorMacRoleRule(aMacRole, aDirectDescendantsFrom) {}
RotorNotMacRoleRule::RotorNotMacRoleRule(NSString* aMacRole)
: RotorMacRoleRule(aMacRole) {}
uint16_t RotorNotMacRoleRule::Match(const AccessibleOrProxy& aAccOrProxy) {
uint16_t result = RotorRule::Match(aAccOrProxy);
// if a match was found in the base-class's Match function,
// it is valid to consider that match again here. if it is
// not different from the desired role, we flip the
// match bit to "unmatch" otherwise, the match persists.
if ((result & nsIAccessibleTraversalRule::FILTER_MATCH)) {
mozAccessible* nativeMatch = GetNativeFromGeckoAccessible(aAccOrProxy);
if ([[nativeMatch moxRole] isEqualToString:mMacRole]) {
result &= ~nsIAccessibleTraversalRule::FILTER_MATCH;
}
}
return result;
}
// Rotor Static Text Rule
RotorStaticTextRule::RotorStaticTextRule(

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

@ -4,6 +4,70 @@
"use strict";
/**
* Test navigation of same/different type content
*/
addAccessibleTask(
`<h1 id="hello">hello</h1>
world<br>
<a href="example.com" id="link">I am a link</a>
<h1 id="goodbye">goodbye</h1>`,
async (browser, accDoc) => {
const searchPred = {
AXSearchKey: "AXSameTypeSearchKey",
AXImmediateDescendantsOnly: 0,
AXResultsLimit: 1,
AXDirection: "AXDirectionNext",
};
const hello = getNativeInterface(accDoc, "hello");
const goodbye = getNativeInterface(accDoc, "goodbye");
const webArea = accDoc.nativeInterface.QueryInterface(
Ci.nsIAccessibleMacInterface
);
searchPred.AXStartElement = hello;
let sameItem = webArea.getParameterizedAttributeValue(
"AXUIElementsForSearchPredicate",
NSDictionary(searchPred)
);
is(sameItem.length, 1, "Found one item");
is(
"goodbye",
sameItem[0].getAttributeValue("AXTitle"),
"Found correct item of same type"
);
searchPred.AXDirection = "AXDirectionPrevious";
searchPred.AXStartElement = goodbye;
sameItem = webArea.getParameterizedAttributeValue(
"AXUIElementsForSearchPredicate",
NSDictionary(searchPred)
);
is(sameItem.length, 1, "Found one item");
is(
"hello",
sameItem[0].getAttributeValue("AXTitle"),
"Found correct item of same type"
);
searchPred.AXSearchKey = "AXDifferentTypeSearchKey";
let diffItem = webArea.getParameterizedAttributeValue(
"AXUIElementsForSearchPredicate",
NSDictionary(searchPred)
);
is(diffItem.length, 1, "Found one item");
is(
"I am a link",
diffItem[0].getAttributeValue("AXValue"),
"Found correct item of different type"
);
}
);
/**
* Test navigation of heading levels
*/