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 328559 800306e9c5733599972acd349c299664db9b3e76
parent 328558 3a4dd49c6e3792095fa03d03b55af6531f08b3f0
child 328560 358d513417fbac311304d801dddfd5c6018f96dd
push id6048
push userkmoir@mozilla.com
push dateMon, 06 Jun 2016 19:02:08 +0000
treeherdermozilla-beta@46d72a56c57d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersyzen
bugs1259023
milestone48.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 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;