зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1668101: Support same/different type naviagation with VO r=eeejay
Differential Revision: https://phabricator.services.mozilla.com/D91833
This commit is contained in:
Родитель
b094c1a9c6
Коммит
c5ff480218
|
@ -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
|
||||
*/
|
||||
|
|
Загрузка…
Ссылка в новой задаче