bug 1168932 - Implement ProxyCreated and ProxyDestroyed to update mozAccessibles r=tbsaunde
authorLorien Hu <lorien@lorienhu.com>
Fri, 29 May 2015 13:42:23 -0400
changeset 246429 f83bbd98a88b4636bce9c97c936d6230036c61ba
parent 246428 6fda72452cf9d1ef9647e0c671a8e96f5b71cceb
child 246430 5ce36ef0515c5d5ae4f3e361c5758e023188ef84
push id28830
push usercbook@mozilla.com
push dateMon, 01 Jun 2015 13:02:44 +0000
treeherdermozilla-central@39c85ec2d644 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstbsaunde
bugs1168932
milestone41.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 1168932 - Implement ProxyCreated and ProxyDestroyed to update mozAccessibles r=tbsaunde
accessible/mac/AccessibleWrap.h
accessible/mac/AccessibleWrap.mm
accessible/mac/Platform.mm
accessible/mac/moz.build
accessible/mac/mozAccessible.h
accessible/mac/mozAccessible.mm
--- a/accessible/mac/AccessibleWrap.h
+++ b/accessible/mac/AccessibleWrap.h
@@ -100,12 +100,14 @@ private:
   /**
    * We have created our native. This does not mean there is one.
    * This can never go back to false.
    * We need it because checking whether we need a native object cost time.
    */
   bool mNativeInited;  
 };
 
+Class GetTypeFromRole(roles::Role aRole);
+
 } // namespace a11y
 } // namespace mozilla
 
 #endif
--- a/accessible/mac/AccessibleWrap.mm
+++ b/accessible/mac/AccessibleWrap.mm
@@ -10,16 +10,17 @@
 #include "nsAccUtils.h"
 #include "Role.h"
 
 #import "mozAccessible.h"
 #import "mozActionElements.h"
 #import "mozHTMLAccessible.h"
 #import "mozTextAccessible.h"
 
+using namespace mozilla;
 using namespace mozilla::a11y;
 
 AccessibleWrap::
   AccessibleWrap(nsIContent* aContent, DocAccessible* aDoc) :
   Accessible(aContent, aDoc), mNativeObject(nil),  
   mNativeInited(false)
 {
 }
@@ -28,18 +29,20 @@ AccessibleWrap::~AccessibleWrap()
 {
 }
 
 mozAccessible* 
 AccessibleWrap::GetNativeObject()
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
   
-  if (!mNativeInited && !mNativeObject && !IsDefunct() && !AncestorIsFlat())
-    mNativeObject = [[GetNativeType() alloc] initWithAccessible:this];
+  if (!mNativeInited && !mNativeObject && !IsDefunct() && !AncestorIsFlat()) {
+    uintptr_t accWrap = reinterpret_cast<uintptr_t>(this);
+    mNativeObject = [[GetNativeType() alloc] initWithAccessible:accWrap];
+  }
   
   mNativeInited = true;
   
   return mNativeObject;
   
   NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
 }
 
@@ -54,58 +57,17 @@ AccessibleWrap::GetNativeInterface(void*
 Class
 AccessibleWrap::GetNativeType () 
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
 
   if (IsXULTabpanels())
     return [mozPaneAccessible class];
 
-  roles::Role role = Role();
-  switch (role) {
-    case roles::COMBOBOX:
-    case roles::PUSHBUTTON:
-    case roles::SPLITBUTTON:
-    case roles::TOGGLE_BUTTON:
-    {
-      // if this button may show a popup, let's make it of the popupbutton type.
-      return [mozButtonAccessible class];
-    }
-    
-    case roles::PAGETAB:
-      return [mozButtonAccessible class];
-
-    case roles::CHECKBUTTON:
-      return [mozCheckboxAccessible class];
-      
-    case roles::HEADING:
-      return [mozHeadingAccessible class];
-
-    case roles::PAGETABLIST:
-      return [mozTabsAccessible class];
-
-    case roles::ENTRY:
-    case roles::STATICTEXT:
-    case roles::CAPTION:
-    case roles::ACCEL_LABEL:
-    case roles::PASSWORD_TEXT:
-      // normal textfield (static or editable)
-      return [mozTextAccessible class];
-
-    case roles::TEXT_LEAF:
-      return [mozTextLeafAccessible class];
-
-    case roles::LINK:
-      return [mozLinkAccessible class];
-
-    default:
-      return [mozAccessible class];
-  }
-  
-  return nil;
+  return GetTypeFromRole(Role());
 
   NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
 }
 
 // this method is very important. it is fired when an accessible object "dies". after this point
 // the object might still be around (because some 3rd party still has a ref to it), but it is
 // in fact 'dead'.
 void
@@ -266,8 +228,57 @@ AccessibleWrap::AncestorIsFlat()
     if (nsAccUtils::MustPrune(parent))
       return true;
 
     parent = parent->Parent();
   }
   // no parent was flat
   return false;
 }
+
+Class
+a11y::GetTypeFromRole(roles::Role aRole) 
+{
+  NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
+
+  switch (aRole) {
+    case roles::COMBOBOX:
+    case roles::PUSHBUTTON:
+    case roles::SPLITBUTTON:
+    case roles::TOGGLE_BUTTON:
+    {
+        return [mozButtonAccessible class];
+    }
+    
+    case roles::PAGETAB:
+      return [mozButtonAccessible class];
+
+    case roles::CHECKBUTTON:
+      return [mozCheckboxAccessible class];
+      
+    case roles::HEADING:
+      return [mozHeadingAccessible class];
+
+    case roles::PAGETABLIST:
+      return [mozTabsAccessible class];
+
+    case roles::ENTRY:
+    case roles::STATICTEXT:
+    case roles::CAPTION:
+    case roles::ACCEL_LABEL:
+    case roles::PASSWORD_TEXT:
+      // normal textfield (static or editable)
+      return [mozTextAccessible class];
+
+    case roles::TEXT_LEAF:
+      return [mozTextLeafAccessible class];
+
+    case roles::LINK:
+      return [mozLinkAccessible class];
+      
+    default:
+      return [mozAccessible class];
+  }
+  
+  return nil;
+
+  NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
+}
--- a/accessible/mac/Platform.mm
+++ b/accessible/mac/Platform.mm
@@ -2,16 +2,17 @@
 /* vim: set ts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #import <Cocoa/Cocoa.h>
 
 #include "Platform.h"
+#include "ProxyAccessible.h"
 
 #include "nsAppShell.h"
 
 namespace mozilla {
 namespace a11y {
 
 // Mac a11y whitelisting
 static bool sA11yShouldBeEnabled = false;
@@ -29,23 +30,33 @@ PlatformInit()
 }
 
 void
 PlatformShutdown()
 {
 }
 
 void
-ProxyCreated(ProxyAccessible*, uint32_t)
+ProxyCreated(ProxyAccessible* aProxy, uint32_t)
 {
+  // Pass in dummy state for now as retrieving proxy state requires IPC.
+  Class type = GetTypeFromRole(aProxy->Role());
+  uintptr_t accWrap = reinterpret_cast<uintptr_t>(aProxy) | IS_PROXY;
+  mozAccessible* mozWrapper = [[type alloc] initWithAccessible:accWrap];
+  aProxy->SetWrapper(reinterpret_cast<uintptr_t>(mozWrapper));
 }
 
 void
-ProxyDestroyed(ProxyAccessible*)
+ProxyDestroyed(ProxyAccessible* aProxy)
 {
+  mozAccessible* wrapper =
+    reinterpret_cast<mozAccessible*>(aProxy->GetWrapper());
+  [wrapper expire];
+  [wrapper release];
+  aProxy->SetWrapper(0);
 }
 
 void
 ProxyEvent(ProxyAccessible*, uint32_t)
 {
 }
 
 void
--- a/accessible/mac/moz.build
+++ b/accessible/mac/moz.build
@@ -25,16 +25,17 @@ UNIFIED_SOURCES += [
     'Platform.mm',
     'RootAccessibleWrap.mm',
 ]
 
 LOCAL_INCLUDES += [
     '/accessible/base',
     '/accessible/generic',
     '/accessible/html',
+    '/accessible/ipc',
     '/accessible/xul',
     '/layout/generic',
     '/layout/xul',
     '/widget',
     '/widget/cocoa',
 ]
 
 FINAL_LIBRARY = 'xul'
--- a/accessible/mac/mozAccessible.h
+++ b/accessible/mac/mozAccessible.h
@@ -52,21 +52,24 @@ static const uintptr_t IS_PROXY = 1;
   mozAccessible* mParent;
 
   /**
    * The role of our gecko accessible.
    */
   mozilla::a11y::role        mRole;
 }
 
-// return the Accessible for this mozAccessible.
-- (mozilla::a11y::AccessibleWrap*) getGeckoAccessible;
+// return the Accessible for this mozAccessible if it exists.
+- (mozilla::a11y::AccessibleWrap*)getGeckoAccessible;
+
+// return the ProxyAccessible for this mozAccessible if it exists.
+- (mozilla::a11y::ProxyAccessible*)getProxyAccessible;
 
 // inits with the gecko owner.
-- (id)initWithAccessible:(mozilla::a11y::AccessibleWrap*)geckoParent;
+- (id)initWithAccessible:(uintptr_t)aGeckoObj;
 
 // our accessible parent (AXParent)
 - (id <mozAccessible>)parent;
 
 // a lazy cache of our accessible children (AXChildren). updated
 - (NSArray*)children;
 
 // returns the size of this accessible.
--- a/accessible/mac/mozAccessible.mm
+++ b/accessible/mac/mozAccessible.mm
@@ -55,25 +55,28 @@ GetClosestInterestingAccessible(id anObj
 
   NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
 }
 
 #pragma mark -
 
 @implementation mozAccessible
  
-- (id)initWithAccessible:(AccessibleWrap*)geckoAccessible
+- (id)initWithAccessible:(uintptr_t)aGeckoAccessible
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
 
   if ((self = [super init])) {
-    mGeckoAccessible = reinterpret_cast<uintptr_t>(geckoAccessible);
-    mRole = geckoAccessible->Role();
+    mGeckoAccessible = aGeckoAccessible;
+    if (aGeckoAccessible & IS_PROXY)
+      mRole = [self getProxyAccessible]->Role();
+    else
+      mRole = [self getGeckoAccessible]->Role();
   }
-   
+
   return self;
 
   NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
 }
 
 - (void)dealloc
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
@@ -87,16 +90,25 @@ GetClosestInterestingAccessible(id anObj
 - (mozilla::a11y::AccessibleWrap*)getGeckoAccessible
 {
   // Check if mGeckoAccessible points at a proxy
   if (mGeckoAccessible & IS_PROXY)
     return nil;
 
   return reinterpret_cast<AccessibleWrap*>(mGeckoAccessible);
 }
+
+- (mozilla::a11y::ProxyAccessible*)getProxyAccessible
+{
+  // Check if mGeckoAccessible points at a proxy
+  if (!(mGeckoAccessible & IS_PROXY))
+    return nil;
+
+  return reinterpret_cast<ProxyAccessible*>(mGeckoAccessible & ~IS_PROXY);
+}
  
 #pragma mark -
 
 - (BOOL)accessibilityIsIgnored
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
 
   // unknown (either unimplemented, or irrelevant) elements are marked as ignored