Bug 1867811 - Expose EXPANDED state for element with popovertarget. r=Jamie

Differential Revision: https://phabricator.services.mozilla.com/D196541
This commit is contained in:
Ziran Sun 2023-12-19 17:30:56 +00:00
Родитель 1c30043b1e
Коммит 584d474cc3
5 изменённых файлов: 78 добавлений и 2 удалений

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

@ -716,6 +716,19 @@ void nsAccessibilityService::TableLayoutGuessMaybeChanged(
}
}
void nsAccessibilityService::PopovertargetMaybeChanged(PresShell* aPresShell,
nsIContent* aContent) {
DocAccessible* document = GetDocAccessible(aPresShell);
if (!document) {
return;
}
if (LocalAccessible* acc = document->GetAccessible(aContent)) {
RefPtr<AccEvent> expandedChangeEvent =
new AccStateChangeEvent(acc, states::EXPANDED);
document->FireDelayedEvent(expandedChangeEvent);
}
}
void nsAccessibilityService::ComboboxOptionMaybeChanged(
PresShell* aPresShell, nsIContent* aMutatingNode) {
DocAccessible* document = GetDocAccessible(aPresShell);

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

@ -180,6 +180,12 @@ class nsAccessibilityService final : public mozilla::a11y::DocManager,
void TableLayoutGuessMaybeChanged(mozilla::PresShell* aPresShell,
nsIContent* aContent);
/**
* Notifies when an element's popovertarget shows/hides.
*/
void PopovertargetMaybeChanged(mozilla::PresShell* aPresShell,
nsIContent* aContent);
/**
* Notifies when a combobox <option> text or label changes.
*/

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

@ -178,6 +178,15 @@ void HTMLButtonAccessible::ActionNameAt(uint8_t aIndex, nsAString& aName) {
uint64_t HTMLButtonAccessible::NativeState() const {
uint64_t state = HyperTextAccessible::NativeState();
dom::Element* elm = Elm();
if (auto* popover = elm->GetEffectivePopoverTargetElement()) {
if (popover->IsPopoverOpen()) {
state |= states::EXPANDED;
} else {
state |= states::COLLAPSED;
}
}
ElementState elmState = mContent->AsElement()->State();
if (elmState.HasState(ElementState::DEFAULT)) state |= states::DEFAULT;

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

@ -482,3 +482,33 @@ addAccessibleTask(
},
{ chrome: true, topLevel: true, remoteIframe: true }
);
/**
* Test caching of the expanded state for popover target element.
*/
addAccessibleTask(
`
<button id="show-popover-btn" popovertarget="mypopover" popovertargetaction="show">Show popover</button>
<button id="hide-popover-btn" popovertarget="mypopover" popovertargetaction="hide">Hide popover</button>
<div id="mypopover" popover>Popover content</div>
`,
async function (browser, docAcc) {
const show = findAccessibleChildByID(docAcc, "show-popover-btn");
const hide = findAccessibleChildByID(docAcc, "hide-popover-btn");
testStates(show, STATE_COLLAPSED, 0);
testStates(hide, STATE_COLLAPSED, 0);
info("Expanding popover");
let onShowing = waitForEvent(EVENT_STATE_CHANGE, show);
await show.doAction(0);
let showingEvent = await onShowing;
testStates(showingEvent.accessible, STATE_EXPANDED, 0);
info("Collapsing popover");
let onHiding = waitForEvent(EVENT_STATE_CHANGE, hide);
await hide.doAction(0);
let hidingEvent = await onHiding;
testStates(hidingEvent.accessible, STATE_COLLAPSED, 0);
},
{ chrome: true, topLevel: true, remoteIframe: true }
);

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

@ -93,6 +93,10 @@
#include "mozilla/dom/ElementBinding.h"
#include "mozilla/dom/ElementInternals.h"
#ifdef ACCESSIBILITY
# include "nsAccessibilityService.h"
#endif
using namespace mozilla;
using namespace mozilla::dom;
@ -2853,14 +2857,28 @@ void nsGenericHTMLFormControlElementWithState::HandlePopoverTargetAction() {
bool canHide = action == PopoverTargetAction::Hide ||
action == PopoverTargetAction::Toggle;
bool shouldHide = canHide && target->IsPopoverOpen();
bool canShow = action == PopoverTargetAction::Show ||
action == PopoverTargetAction::Toggle;
bool shouldShow = canShow && !target->IsPopoverOpen();
if (canHide && target->IsPopoverOpen()) {
if (shouldHide) {
target->HidePopover(IgnoreErrors());
} else if (canShow && !target->IsPopoverOpen()) {
} else if (shouldShow) {
target->ShowPopoverInternal(this, IgnoreErrors());
}
#ifdef ACCESSIBILITY
// Notify the accessibility service about the change.
if (shouldHide || shouldShow) {
if (RefPtr<Document> doc = GetComposedDoc()) {
if (PresShell* presShell = doc->GetPresShell()) {
if (nsAccessibilityService* accService = GetAccService()) {
accService->PopovertargetMaybeChanged(presShell, this);
}
}
}
}
#endif
}
void nsGenericHTMLFormControlElementWithState::GetInvokeAction(