Bug 1198336 - P3: Implement AXLiveRegionSearchKey. r=morgan

I think VoiceOver uses this to pull in all live regions so it
can check for deletions when they change later on.

Depends on D96292

Differential Revision: https://phabricator.services.mozilla.com/D96293
This commit is contained in:
Eitan Isaacson 2020-11-16 20:16:44 +00:00
Родитель 56f38afb59
Коммит 5eee7bf4ed
4 изменённых файлов: 44 добавлений и 16 удалений

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

@ -329,6 +329,13 @@ using namespace mozilla::a11y;
: RotorMacRoleRule(@"AXTextField"); : RotorMacRoleRule(@"AXTextField");
[matches addObjectsFromArray:[self getMatchesForRule:rule]]; [matches addObjectsFromArray:[self getMatchesForRule:rule]];
} }
if ([key isEqualToString:@"AXLiveRegionSearchKey"]) {
RotorLiveRegionRule rule = mImmediateDescendantsOnly
? RotorLiveRegionRule(geckoRootAcc)
: RotorLiveRegionRule();
[matches addObjectsFromArray:[self getMatchesForRule:rule]];
}
} }
return matches; return matches;

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

@ -113,6 +113,15 @@ class RotorHeadingLevelRule : public RotorRoleRule {
int32_t mLevel; int32_t mLevel;
}; };
class RotorLiveRegionRule : public RotorRule {
public:
explicit RotorLiveRegionRule(AccessibleOrProxy& aDirectDescendantsFrom)
: RotorRule(aDirectDescendantsFrom) {}
explicit RotorLiveRegionRule() : RotorRule() {}
uint16_t Match(const AccessibleOrProxy& aAccOrProxy) override;
};
/** /**
* This rule matches all accessibles with roles::OUTLINEITEM. If * This rule matches all accessibles with roles::OUTLINEITEM. If
* outlines are nested, it ignores the nested subtree and returns * outlines are nested, it ignores the nested subtree and returns

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

@ -308,6 +308,18 @@ uint16_t RotorHeadingLevelRule::Match(const AccessibleOrProxy& aAccOrProxy) {
return result; return result;
} }
uint16_t RotorLiveRegionRule::Match(const AccessibleOrProxy& aAccOrProxy) {
uint16_t result = RotorRule::Match(aAccOrProxy);
if ((result & nsIAccessibleTraversalRule::FILTER_MATCH)) {
mozAccessible* nativeMatch = GetNativeFromGeckoAccessible(aAccOrProxy);
if (![nativeMatch moxIsLiveRegion]) {
result &= ~nsIAccessibleTraversalRule::FILTER_MATCH;
}
}
return result;
}
// Outline Rule // Outline Rule
OutlineRule::OutlineRule() : RotorRule(){}; OutlineRule::OutlineRule() : RotorRule(){};

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

@ -99,22 +99,22 @@ addAccessibleTask(
<div id="status" role="status"></div> <div id="status" role="status"></div>
<output id="output"></output>`; <output id="output"></output>`;
}); });
await loadComplete; let webArea = (await loadComplete)[0];
liveRegionRemoved = waitForEvent(EVENT_LIVE_REGION_REMOVED, "status"); is(webArea.getAttributeValue("AXRole"), "AXWebArea", "web area yeah");
await SpecialPowers.spawn(browser, [], () => { const searchPred = {
content.document AXSearchKey: "AXLiveRegionSearchKey",
.getElementById("status") AXResultsLimit: -1,
.setAttribute("aria-live", "off"); AXDirection: "AXDirectionNext",
}); };
await liveRegionRemoved; const liveRegions = webArea.getParameterizedAttributeValue(
"AXUIElementsForSearchPredicate",
liveRegionRemoved = waitForEvent(EVENT_LIVE_REGION_REMOVED, "output"); NSDictionary(searchPred)
await SpecialPowers.spawn(browser, [], () => { );
content.document Assert.deepEqual(
.getElementById("output") liveRegions.map(r => r.getAttributeValue("AXDOMIdentifier")),
.setAttribute("aria-live", "off"); ["region-1", "region-2", "status", "output"],
}); "SearchPredicate returned all live regions"
await liveRegionRemoved; );
} }
); );