Revert "Bug 1899960 - P2: Imply an unavailable state if focusable is in unavailable subtree. r=Jamie" for casuing junit failures.

This reverts commit 5906bff6eb.

This reverts commit f491f2de6e.

This reverts commit 047d7acfa2.
This commit is contained in:
Serban Stanca
2025-05-23 23:39:09 +03:00
committed by sstanca@mozilla.com
parent 2a2d6d70d7
commit 254eb70a9d
8 changed files with 40 additions and 79 deletions

View File

@@ -295,9 +295,9 @@ const uint64_t LAST_ENTRY = CURRENT;
/**
* States that must be calculated by RemoteAccessible and are thus not cached.
*/
const uint64_t kRemoteCalculatedStates = states::FOCUSED | states::INVISIBLE |
states::OFFSCREEN | states::SENSITIVE |
states::OPAQUE1;
const uint64_t kRemoteCalculatedStates =
states::FOCUSED | states::INVISIBLE | states::OFFSCREEN | states::ENABLED |
states::SENSITIVE | states::COLLAPSED | states::OPAQUE1;
} // namespace a11y
} // namespace mozilla

View File

@@ -698,39 +698,6 @@ void Accessible::ApplyImplicitState(uint64_t& aState) const {
if (Opacity() == 1.0f && !(aState & states::INVISIBLE)) {
aState |= states::OPAQUE1;
}
const uint32_t kExpandCollapseStates = states::COLLAPSED | states::EXPANDED;
if ((aState & kExpandCollapseStates) == kExpandCollapseStates) {
// Cannot be both expanded and collapsed -- this happens in ARIA expanded
// combobox because of limitation of ARIAMap.
// XXX: Perhaps we will be able to make this less hacky if we support
// extended states in ARIAMap, e.g. derive COLLAPSED from
// EXPANDABLE && !EXPANDED.
aState &= ~states::COLLAPSED;
}
if (!(aState & states::UNAVAILABLE)) {
aState |= states::ENABLED | states::SENSITIVE;
}
if (aState & kExpandCollapseStates) {
aState |= states::EXPANDABLE;
}
if (aState & states::FOCUSABLE && !(aState & states::UNAVAILABLE)) {
// Propagate UNAVAILABLE state from ancestors down to any focusable
// descendant.
for (auto ancestor = Parent(); ancestor; ancestor = ancestor->Parent()) {
if (ancestor->IsDoc()) {
break;
}
if (ancestor->State() & states::UNAVAILABLE) {
aState |= states::UNAVAILABLE;
break;
}
}
}
}
bool Accessible::NameIsEmpty() const {

View File

@@ -1602,14 +1602,26 @@ void LocalAccessible::ARIAGroupPosition(int32_t* aLevel, int32_t* aSetSize,
}
}
uint64_t LocalAccessible::ExplicitState() const {
uint64_t LocalAccessible::State() {
if (IsDefunct()) return states::DEFUNCT;
uint64_t state = NativeState();
// Apply ARIA states to be sure accessible states will be overridden.
ApplyARIAState(&state);
const uint32_t kExpandCollapseStates = states::COLLAPSED | states::EXPANDED;
if ((state & kExpandCollapseStates) == kExpandCollapseStates) {
// Cannot be both expanded and collapsed -- this happens in ARIA expanded
// combobox because of limitation of ARIAMap.
// XXX: Perhaps we will be able to make this less hacky if we support
// extended states in ARIAMap, e.g. derive COLLAPSED from
// EXPANDABLE && !EXPANDED.
state &= ~states::COLLAPSED;
}
if (!(state & states::UNAVAILABLE)) {
state |= states::ENABLED | states::SENSITIVE;
// If the object is a current item of container widget then mark it as
// ACTIVE. This allows screen reader virtual buffer modes to know which
// descendant is the current one that would get focus if the user navigates
@@ -1618,12 +1630,10 @@ uint64_t LocalAccessible::ExplicitState() const {
if (widget && widget->CurrentItem() == this) state |= states::ACTIVE;
}
return state;
if ((state & states::COLLAPSED) || (state & states::EXPANDED)) {
state |= states::EXPANDABLE;
}
uint64_t LocalAccessible::State() {
uint64_t state = ExplicitState();
ApplyImplicitState(state);
return state;
}
@@ -1665,7 +1675,18 @@ void LocalAccessible::ApplyARIAState(uint64_t* aState) const {
}
}
if (!(*aState & states::FOCUSABLE)) {
if (*aState & states::FOCUSABLE) {
// Propogate aria-disabled from ancestors down to any focusable descendant.
const LocalAccessible* ancestor = this;
while ((ancestor = ancestor->LocalParent()) && !ancestor->IsDoc()) {
dom::Element* el = ancestor->Elm();
if (el && nsAccUtils::ARIAAttrValueIs(el, nsGkAtoms::aria_disabled,
nsGkAtoms::_true, eCaseMatters)) {
*aState |= states::UNAVAILABLE;
break;
}
}
} else {
// Sometimes, we use aria-activedescendant targeting something which isn't
// actually a descendant. This is technically a spec violation, but it's a
// useful hack which makes certain things much easier. For example, we use
@@ -3917,7 +3938,7 @@ already_AddRefed<AccAttributes> LocalAccessible::BundleFieldsForCache(
if (IsInitialPush(CacheDomain::State)) {
// Most states are updated using state change events, so we only send
// these for the initial cache push.
uint64_t state = ExplicitState();
uint64_t state = State();
// Exclude states which must be calculated by RemoteAccessible.
state &= ~kRemoteCalculatedStates;
fields->SetAttribute(CacheKey::State, state);

View File

@@ -765,8 +765,6 @@ class LocalAccessible : public nsISupports, public Accessible {
*/
void NativeDescription(nsString& aDescription) const;
uint64_t ExplicitState() const;
/**
* Return object attributes provided by native markup. It doesn't take into
* account ARIA.

View File

@@ -1580,6 +1580,13 @@ uint64_t RemoteAccessible::State() {
mCachedFields->GetAttribute<uint64_t>(CacheKey::State)) {
VERIFY_CACHE(CacheDomain::State);
state = *rawState;
// Handle states that are derived from other states.
if (!(state & states::UNAVAILABLE)) {
state |= states::ENABLED | states::SENSITIVE;
}
if (state & states::EXPANDABLE && !(state & states::EXPANDED)) {
state |= states::COLLAPSED;
}
}
ApplyImplicitState(state);

View File

@@ -778,7 +778,6 @@ addAccessibleTask(
</fieldset>
<div id="ariaDisabled" aria-disabled="true" role="button">ariaDisabled</div>
<input id="enabled">
<div id="ariaDisabledGroup" aria-disabled="true"><input id="inAriaDisabledGroup"></div>
`,
async function testUnavailable(browser, docAcc) {
const input = findAccessibleChildByID(docAcc, "input");
@@ -841,28 +840,6 @@ addAccessibleTask(
// Test a control that is initially enabled.
const enabled = findAccessibleChildByID(docAcc, "enabled");
testStates(enabled, 0, 0, STATE_UNAVAILABLE);
const ariaDisabledGroup = findAccessibleChildByID(
docAcc,
"ariaDisabledGroup"
);
const inAriaDisabledGroup = findAccessibleChildByID(
docAcc,
"inAriaDisabledGroup"
);
testStates(ariaDisabledGroup, STATE_UNAVAILABLE);
testStates(inAriaDisabledGroup, STATE_UNAVAILABLE);
info("Enabling ariaDisabledGroup");
changed = waitForStateChange(ariaDisabledGroup, STATE_UNAVAILABLE, false);
await invokeSetAttribute(
browser,
"ariaDisabledGroup",
"aria-disabled",
null
);
await changed;
testStates(ariaDisabledGroup, 0, 0, STATE_UNAVAILABLE);
testStates(inAriaDisabledGroup, 0, 0, STATE_UNAVAILABLE);
},
{ chrome: true, topLevel: true }
);

View File

@@ -15,8 +15,6 @@
src="../events.js" />
<script type="application/javascript"
src="../role.js" />
<script type="application/javascript"
src="../states.js" />
<script type="application/javascript">
<![CDATA[
@@ -35,7 +33,6 @@
this.finalCheck = function openMenu_finalCheck()
{
testStates(aID, STATE_FLOATING, 0, STATE_INVISIBLE | STATE_OFFSCREEN | STATE_COLLAPSED);
testAccessibleTree(aID, aTree);
}
@@ -116,11 +113,6 @@
{
return "close menu " + prettyName(aID);
}
this.finalCheck = function closeMenu_finalCheck()
{
testStates(aID, STATE_FLOATING | STATE_INVISIBLE | STATE_OFFSCREEN | STATE_COLLAPSED, 0);
}
}
//gA11yEventDumpToConsole = true;

View File

@@ -339,8 +339,7 @@ uint64_t XULMenupopupAccessible::NativeState() const {
#ifdef DEBUG
// We are onscreen if our parent is active
nsMenuPopupFrame* menuPopupFrame = do_QueryFrame(GetFrame());
bool isActive = menuPopupFrame ? menuPopupFrame->IsOpen() : false;
bool isActive = mContent->AsElement()->HasAttr(nsGkAtoms::menuactive);
if (!isActive) {
LocalAccessible* parent = LocalParent();
if (parent) {