Revert "Bug 1899960 - P2: Imply an unavailable state if focusable is in unavailable subtree. r=Jamie" for casuing junit failures.
This reverts commit5906bff6eb. This reverts commitf491f2de6e. This reverts commit047d7acfa2.
This commit is contained in:
committed by
sstanca@mozilla.com
parent
2a2d6d70d7
commit
254eb70a9d
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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,11 +1630,9 @@ uint64_t LocalAccessible::ExplicitState() const {
|
||||
if (widget && widget->CurrentItem() == this) state |= states::ACTIVE;
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
uint64_t LocalAccessible::State() {
|
||||
uint64_t state = ExplicitState();
|
||||
if ((state & states::COLLAPSED) || (state & states::EXPANDED)) {
|
||||
state |= states::EXPANDABLE;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 }
|
||||
);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user