diff --git a/accessible/ipc/DocAccessibleChild.cpp b/accessible/ipc/DocAccessibleChild.cpp index c23b6c64166..c77764d4a96 100644 --- a/accessible/ipc/DocAccessibleChild.cpp +++ b/accessible/ipc/DocAccessibleChild.cpp @@ -144,6 +144,20 @@ DocAccessibleChild::RecvState(const uint64_t& aID, uint64_t* aState) return true; } +bool +DocAccessibleChild::RecvNativeState(const uint64_t& aID, uint64_t* aState) +{ + Accessible* acc = IdToAccessible(aID); + if (!acc) { + *aState = states::DEFUNCT; + return true; + } + + *aState = acc->NativeState(); + + return true; +} + bool DocAccessibleChild::RecvName(const uint64_t& aID, nsString* aName) { diff --git a/accessible/ipc/DocAccessibleChild.h b/accessible/ipc/DocAccessibleChild.h index d9cc9421e3a..5aae0ead9f2 100644 --- a/accessible/ipc/DocAccessibleChild.h +++ b/accessible/ipc/DocAccessibleChild.h @@ -63,6 +63,11 @@ public: */ virtual bool RecvState(const uint64_t& aID, uint64_t* aState) override; + /* + * Return the native state for the accessible with given ID. + */ + virtual bool RecvNativeState(const uint64_t& aID, uint64_t* aState) override; + /* * Get the name for the accessible with given id. */ diff --git a/accessible/ipc/PDocAccessible.ipdl b/accessible/ipc/PDocAccessible.ipdl index b93c057c2ff..2e705dc4de0 100644 --- a/accessible/ipc/PDocAccessible.ipdl +++ b/accessible/ipc/PDocAccessible.ipdl @@ -73,6 +73,7 @@ child: // Accessible prio(high) sync State(uint64_t aID) returns(uint64_t states); + prio(high) sync NativeState(uint64_t aID) returns(uint64_t states); prio(high) sync Name(uint64_t aID) returns(nsString name); prio(high) sync Value(uint64_t aID) returns(nsString value); prio(high) sync Help(uint64_t aID) returns(nsString help); diff --git a/accessible/ipc/ProxyAccessible.cpp b/accessible/ipc/ProxyAccessible.cpp index 818e0a8ed38..cf1bd18d10f 100644 --- a/accessible/ipc/ProxyAccessible.cpp +++ b/accessible/ipc/ProxyAccessible.cpp @@ -83,6 +83,14 @@ ProxyAccessible::State() const return state; } +uint64_t +ProxyAccessible::NativeState() const +{ + uint64_t state = 0; + unused << mDoc->SendNativeState(mID, &state); + return state; +} + void ProxyAccessible::Name(nsString& aName) const { diff --git a/accessible/ipc/ProxyAccessible.h b/accessible/ipc/ProxyAccessible.h index 62aa50fc722..b7681950894 100644 --- a/accessible/ipc/ProxyAccessible.h +++ b/accessible/ipc/ProxyAccessible.h @@ -79,6 +79,11 @@ public: */ uint64_t State() const; + /* + * Return the native states for the proxied accessible. + */ + uint64_t NativeState() const; + /* * Set aName to the name of the proxied accessible. */ diff --git a/accessible/mac/mozActionElements.mm b/accessible/mac/mozActionElements.mm index 254019ed56a..c2668dd1bf2 100644 --- a/accessible/mac/mozActionElements.mm +++ b/accessible/mac/mozActionElements.mm @@ -141,21 +141,31 @@ enum CheckboxValue { - (BOOL)isTab { - AccessibleWrap* accWrap = [self getGeckoAccessible]; - return (accWrap && (accWrap->Role() == roles::PAGETAB)); + if (AccessibleWrap* accWrap = [self getGeckoAccessible]) + return accWrap->Role() == roles::PAGETAB; + + if (ProxyAccessible* proxy = [self getProxyAccessible]) + return proxy->Role() == roles::PAGETAB; + + return false; } - (BOOL)hasPopup { - AccessibleWrap* accWrap = [self getGeckoAccessible]; - return accWrap && (accWrap->NativeState() & mozilla::a11y::states::HASPOPUP); + if (AccessibleWrap* accWrap = [self getGeckoAccessible]) + return accWrap->NativeState() & states::HASPOPUP; + + if (ProxyAccessible* proxy = [self getProxyAccessible]) + return proxy->NativeState() & states::HASPOPUP; + + return false; } @end @implementation mozCheckboxAccessible -- (NSString*)accessibilityActionDescription:(NSString*)action +- (NSString*)accessibilityActionDescription:(NSString*)action { NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL; @@ -173,7 +183,11 @@ enum CheckboxValue { - (int)isChecked { - uint64_t state = [self getGeckoAccessible]->NativeState(); + uint64_t state = 0; + if (AccessibleWrap* accWrap = [self getGeckoAccessible]) + state = accWrap->NativeState(); + else if (ProxyAccessible* proxy = [self getProxyAccessible]) + state = proxy->NativeState(); // check if we're checked or in a mixed state if (state & states::CHECKED) { @@ -279,13 +293,19 @@ enum CheckboxValue { - (NSUInteger)accessibilityArrayAttributeCount:(NSString*)attribute { - if (![self getGeckoAccessible]) + AccessibleWrap* accWrap = [self getGeckoAccessible]; + ProxyAccessible* proxy = [self getProxyAccessible]; + if (!accWrap && !proxy) return 0; // By default this calls -[[mozAccessible children] count]. // Since we don't cache mChildren. This is faster. - if ([attribute isEqualToString:NSAccessibilityChildrenAttribute]) - return [self getGeckoAccessible]->ChildCount() ? 1 : 0; + if ([attribute isEqualToString:NSAccessibilityChildrenAttribute]) { + if (accWrap) + return accWrap->ChildCount() ? 1 : 0; + + return proxy->ChildrenCount() ? 1 : 0; + } return [super accessibilityArrayAttributeCount:attribute]; }