bug 1259023 - make nsIAccessible.parent work with proxies r=yzen
☠☠ backed out by 6378e50f68ff ☠ ☠
authorTrevor Saunders <tbsaunde@tbsaunde.org>
Tue, 22 Mar 2016 14:53:33 -0400
changeset 290747 800306e9c5733599972acd349c299664db9b3e76
parent 290746 3a4dd49c6e3792095fa03d03b55af6531f08b3f0
child 290748 358d513417fbac311304d801dddfd5c6018f96dd
push id19656
push usergwagner@mozilla.com
push dateMon, 04 Apr 2016 13:43:23 +0000
treeherderb2g-inbound@e99061fde28a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersyzen
bugs1259023
milestone48.0a1
bug 1259023 - make nsIAccessible.parent work with proxies r=yzen
accessible/atk/AccessibleWrap.cpp
accessible/atk/nsMai.h
accessible/base/AccessibleOrProxy.cpp
accessible/base/AccessibleOrProxy.h
accessible/base/moz.build
accessible/xpcom/xpcAccessible.cpp
--- a/accessible/atk/AccessibleWrap.cpp
+++ b/accessible/atk/AccessibleWrap.cpp
@@ -788,34 +788,19 @@ GetLocaleCB(AtkObject* aAtkObj)
 }
 
 AtkObject *
 getParentCB(AtkObject *aAtkObj)
 {
   if (aAtkObj->accessible_parent)
     return aAtkObj->accessible_parent;
 
-  AtkObject* atkParent = nullptr;
-  if (AccessibleWrap* wrapper = GetAccessibleWrap(aAtkObj)) {
-    Accessible* parent = wrapper->Parent();
-    atkParent = parent ? AccessibleWrap::GetAtkObject(parent) : nullptr;
-  } else if (ProxyAccessible* proxy = GetProxy(aAtkObj)) {
-    ProxyAccessible* parent = proxy->Parent();
-    if (parent) {
-      atkParent = GetWrapperFor(parent);
-    } else {
-      // Otherwise this should be the proxy for the tab's top level document.
-      Accessible* outerDocParent = proxy->OuterDocOfRemoteBrowser();
-      NS_ASSERTION(outerDocParent, "this document should have an outerDoc as a parent");
-      if (outerDocParent) {
-        atkParent = AccessibleWrap::GetAtkObject(outerDocParent);
-      }
-    }
-  }
-
+  AccessibleOrProxy acc = GetInternalObj(aAtkObj);
+  AccessibleOrProxy parent = acc.Parent();
+  AtkObject* atkParent = GetWrapperFor(parent);
   if (atkParent)
     atk_object_set_parent(aAtkObj, atkParent);
 
   return aAtkObj->accessible_parent;
 }
 
 gint
 getChildCountCB(AtkObject *aAtkObj)
@@ -1096,16 +1081,26 @@ GetInternalObj(AtkObject* aObj)
 }
 
 AtkObject*
 GetWrapperFor(ProxyAccessible* aProxy)
 {
   return reinterpret_cast<AtkObject*>(aProxy->GetWrapper() & ~IS_PROXY);
 }
 
+AtkObject*
+GetWrapperFor(AccessibleOrProxy aObj)
+{
+  if (aObj.IsProxy()) {
+      return GetWrapperFor(aObj.AsProxy());
+      }
+
+      return AccessibleWrap::GetAtkObject(aObj.AsAccessible());
+      }
+
 static uint16_t
 GetInterfacesForProxy(ProxyAccessible* aProxy, uint32_t aInterfaces)
 {
   uint16_t interfaces = 1 << MAI_INTERFACE_COMPONENT;
   if (aInterfaces & Interfaces::HYPERTEXT)
     interfaces |= (1 << MAI_INTERFACE_HYPERTEXT) | (1 << MAI_INTERFACE_TEXT)
         | (1 << MAI_INTERFACE_EDITABLE_TEXT);
 
--- a/accessible/atk/nsMai.h
+++ b/accessible/atk/nsMai.h
@@ -64,16 +64,17 @@ typedef struct _MaiAtkSocketClass
 {
   AtkSocketClass parent_class;
 } MaiAtkSocketClass;
 
 mozilla::a11y::AccessibleWrap* GetAccessibleWrap(AtkObject* aAtkObj);
 mozilla::a11y::ProxyAccessible* GetProxy(AtkObject* aAtkObj);
 mozilla::a11y::AccessibleOrProxy GetInternalObj(AtkObject* aObj);
 AtkObject* GetWrapperFor(mozilla::a11y::ProxyAccessible* aProxy);
+AtkObject* GetWrapperFor(mozilla::a11y::AccessibleOrProxy aObj);
 
 extern int atkMajorVersion, atkMinorVersion;
 
 /**
  * Return true if the loaded version of libatk-1.0.so is at least
  * aMajor.aMinor.0.
  */
 static inline bool
new file mode 100644
--- /dev/null
+++ b/accessible/base/AccessibleOrProxy.cpp
@@ -0,0 +1,27 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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/. */
+
+#include "AccessibleOrProxy.h"
+
+AccessibleOrProxy
+AccessibleOrProxy::Parent() const
+{
+  if (IsAccessible()) {
+    return AsAccessible()->Parent();
+  }
+
+  ProxyAccessible* proxy = AsProxy();
+  if (!proxy) {
+    return nullptr;
+  }
+
+  if (ProxyAccessible* parent = proxy->Parent()) {
+    return parent;
+  }
+
+  // Otherwise this should be the proxy for the tab's top level document.
+  return proxy->OuterDocOfRemoteBrowser();
+}
--- a/accessible/base/AccessibleOrProxy.h
+++ b/accessible/base/AccessibleOrProxy.h
@@ -101,16 +101,18 @@ public:
   {
     if (IsProxy()) {
       return AsProxy()->Role();
     }
 
     return AsAccessible()->Role();
   }
 
+  AccessibleOrProxy Parent() const;
+
   // XXX these are implementation details that ideally would not be exposed.
   uintptr_t Bits() const { return mBits; }
   void SetBits(uintptr_t aBits) { mBits = aBits; }
 
 private:
   uintptr_t mBits;
   static const uintptr_t IS_PROXY = 0x1;
 };
--- a/accessible/base/moz.build
+++ b/accessible/base/moz.build
@@ -22,16 +22,17 @@ EXPORTS.mozilla.a11y += [
 
 if CONFIG['MOZ_DEBUG']:
     EXPORTS.mozilla.a11y += [
         'Logging.h',
     ]
 
 UNIFIED_SOURCES += [
     'AccCollector.cpp',
+    'AccessibleOrProxy.cpp',
     'AccEvent.cpp',
     'AccGroupInfo.cpp',
     'AccIterator.cpp',
     'ARIAMap.cpp',
     'ARIAStateMap.cpp',
     'Asserts.cpp',
     'DocManager.cpp',
     'EventQueue.cpp',
--- a/accessible/xpcom/xpcAccessible.cpp
+++ b/accessible/xpcom/xpcAccessible.cpp
@@ -20,20 +20,21 @@
 
 using namespace mozilla::a11y;
 
 NS_IMETHODIMP
 xpcAccessible::GetParent(nsIAccessible** aParent)
 {
   NS_ENSURE_ARG_POINTER(aParent);
   *aParent = nullptr;
-  if (!Intl())
+  if (IntlGeneric().IsNull())
     return NS_ERROR_FAILURE;
 
-  NS_IF_ADDREF(*aParent = ToXPC(Intl()->Parent()));
+  AccessibleOrProxy parent = IntlGeneric().Parent();
+  NS_IF_ADDREF(*aParent = ToXPC(parent));
   return NS_OK;
 }
 
 NS_IMETHODIMP
 xpcAccessible::GetNextSibling(nsIAccessible** aNextSibling)
 {
   NS_ENSURE_ARG_POINTER(aNextSibling);
   *aNextSibling = nullptr;