Bug 1187739 - (Part 1) Handle proxies in mozActionElements r=tbsaunde
authorLorien Hu <lorien@lorienhu.com>
Tue, 04 Aug 2015 14:56:18 -0400
changeset 256139 2b0b584ce01f718c9c4807121b9096936857edb1
parent 256138 01f5097128e5e0f49aad5781fdc4b12a6a11cbc2
child 256140 689c420edf65720d98bbe9e8f9836f28b83c2498
push id63239
push userlhu@mozilla.com
push dateTue, 04 Aug 2015 20:03:28 +0000
treeherdermozilla-inbound@689c420edf65 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstbsaunde
bugs1187739
milestone42.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1187739 - (Part 1) Handle proxies in mozActionElements r=tbsaunde
accessible/ipc/DocAccessibleChild.cpp
accessible/ipc/DocAccessibleChild.h
accessible/ipc/PDocAccessible.ipdl
accessible/ipc/ProxyAccessible.cpp
accessible/ipc/ProxyAccessible.h
accessible/mac/mozActionElements.mm
--- a/accessible/ipc/DocAccessibleChild.cpp
+++ b/accessible/ipc/DocAccessibleChild.cpp
@@ -140,16 +140,30 @@ DocAccessibleChild::RecvState(const uint
   }
 
   *aState = acc->State();
 
   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)
 {
   Accessible* acc = IdToAccessible(aID);
   if (!acc)
     return true;
 
   acc->Name(*aName);
   return true;
--- a/accessible/ipc/DocAccessibleChild.h
+++ b/accessible/ipc/DocAccessibleChild.h
@@ -59,16 +59,21 @@ public:
   void ShowEvent(AccShowEvent* aShowEvent);
 
   /*
    * Return the state for the accessible with given ID.
    */
   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.
    */
   virtual bool RecvName(const uint64_t& aID, nsString* aName) override;
 
   virtual bool RecvValue(const uint64_t& aID, nsString* aValue) override;
 
   virtual bool RecvHelp(const uint64_t& aID, nsString* aHelp) override;
 
--- a/accessible/ipc/PDocAccessible.ipdl
+++ b/accessible/ipc/PDocAccessible.ipdl
@@ -68,16 +68,17 @@ parent:
    */
   BindChildDoc(PDocAccessible aChildDoc, uint64_t aID);
 
 child:
   __delete__();
 
   // 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);
   prio(high) sync Description(uint64_t aID) returns(nsString desc);
   prio(high) sync Attributes(uint64_t aID) returns(Attribute[] attributes);
   prio(high) sync RelationByType(uint64_t aID, uint32_t aRelationType)
     returns(uint64_t[] targets);
   prio(high) sync Relations(uint64_t aID) returns(RelationTargets[] relations);
--- a/accessible/ipc/ProxyAccessible.cpp
+++ b/accessible/ipc/ProxyAccessible.cpp
@@ -78,16 +78,24 @@ ProxyAccessible::MustPruneChildren() con
 uint64_t
 ProxyAccessible::State() const
 {
   uint64_t state = 0;
   unused << mDoc->SendState(mID, &state);
   return state;
 }
 
+uint64_t
+ProxyAccessible::NativeState() const
+{
+  uint64_t state = 0;
+  unused << mDoc->SendNativeState(mID, &state);
+  return state;
+}
+
 void
 ProxyAccessible::Name(nsString& aName) const
 {
   unused << mDoc->SendName(mID, &aName);
 }
 
 void
 ProxyAccessible::Value(nsString& aValue) const
--- a/accessible/ipc/ProxyAccessible.h
+++ b/accessible/ipc/ProxyAccessible.h
@@ -75,16 +75,21 @@ public:
   role Role() const { return mRole; }
 
   /*
    * Return the states for the proxied accessible.
    */
   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.
    */
   void Name(nsString& aName) const;
 
   /*
    * Set aValue to the value of the proxied accessible.
    */
   void Value(nsString& aValue) const;
--- a/accessible/mac/mozActionElements.mm
+++ b/accessible/mac/mozActionElements.mm
@@ -136,31 +136,41 @@ enum CheckboxValue {
 {
   // both buttons and checkboxes have only one action. we should really stop using arbitrary
   // arrays with actions, and define constants for these actions.
   [self getGeckoAccessible]->DoAction(0);
 }
 
 - (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;
 
   if ([action isEqualToString:NSAccessibilityPressAction]) {
     if ([self isChecked] != kUnchecked)
       return @"uncheck checkbox"; // XXX: localize this later?
 
     return @"check checkbox"; // XXX: localize this later?
@@ -168,17 +178,21 @@ enum CheckboxValue {
 
   return nil;
 
   NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
 }
 
 - (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) {
     return (state & states::MIXED) ? kMixed : kChecked;
   }
 
   return kUnchecked;
 }
@@ -274,23 +288,29 @@ enum CheckboxValue {
 }
 
 @end
 
 @implementation mozPaneAccessible
 
 - (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];
 }
 
 - (NSArray*)children
 {
   if (![self getGeckoAccessible])
     return nil;