Bug 1171995 - Part 5: Handle proxies in mozAccessible accessibilityAttributeValue r=tbsaunde
authorLorien Hu <lorien@lorienhu.com>
Thu, 16 Jul 2015 17:34:52 -0400
changeset 253299 73f2e7591ff02eecfc7de1961d2debac799a3941
parent 253298 79131088413abc7fc2f331c97103ee5d9407f47b
child 253300 e27f10f740a22bd8e841c5822d0ec22fa5d7f4a2
push id62398
push userlhu@mozilla.com
push dateThu, 16 Jul 2015 21:35:56 +0000
treeherdermozilla-inbound@5a04fa687d38 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstbsaunde
bugs1171995
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 1171995 - Part 5: Handle proxies in mozAccessible accessibilityAttributeValue r=tbsaunde
accessible/ipc/ProxyAccessible.cpp
accessible/ipc/ProxyAccessible.h
accessible/mac/moz.build
accessible/mac/mozAccessible.mm
--- a/accessible/ipc/ProxyAccessible.cpp
+++ b/accessible/ipc/ProxyAccessible.cpp
@@ -515,25 +515,37 @@ uint32_t
 ProxyAccessible::RowExtent()
 {
   uint32_t extent = 0;
   unused << mDoc->SendRowExtent(mID, &extent);
   return extent;
 }
 
 void
-ProxyAccessible::ColHeaderCells(nsTArray<uint64_t>* aCells)
+ProxyAccessible::ColHeaderCells(nsTArray<ProxyAccessible*>* aCells)
 {
-  unused << mDoc->SendColHeaderCells(mID, aCells);
+  nsTArray<uint64_t> targetIDs;
+  unused << mDoc->SendColHeaderCells(mID, &targetIDs);
+
+  size_t targetCount = targetIDs.Length();
+  for (size_t i = 0; i < targetCount; i++) {
+    aCells->AppendElement(mDoc->GetAccessible(targetIDs[i]));
+  }
 }
 
 void
-ProxyAccessible::RowHeaderCells(nsTArray<uint64_t>* aCells)
+ProxyAccessible::RowHeaderCells(nsTArray<ProxyAccessible*>* aCells)
 {
-  unused << mDoc->SendRowHeaderCells(mID, aCells);
+  nsTArray<uint64_t> targetIDs;
+  unused << mDoc->SendRowHeaderCells(mID, &targetIDs);
+
+  size_t targetCount = targetIDs.Length();
+  for (size_t i = 0; i < targetCount; i++) {
+    aCells->AppendElement(mDoc->GetAccessible(targetIDs[i]));
+  }
 }
 
 bool
 ProxyAccessible::IsCellSelected()
 {
   bool selected = false;
   unused << mDoc->SendIsCellSelected(mID, &selected);
   return selected;
--- a/accessible/ipc/ProxyAccessible.h
+++ b/accessible/ipc/ProxyAccessible.h
@@ -219,19 +219,19 @@ public:
   uint32_t ColIdx();
 
   uint32_t RowIdx();
 
   uint32_t ColExtent();
 
   uint32_t RowExtent();
 
-  void ColHeaderCells(nsTArray<uint64_t>* aCells);
+  void ColHeaderCells(nsTArray<ProxyAccessible*>* aCells);
 
-  void RowHeaderCells(nsTArray<uint64_t>* aCells);
+  void RowHeaderCells(nsTArray<ProxyAccessible*>* aCells);
 
   bool IsCellSelected();
 
   ProxyAccessible* TableCaption();
   void TableSummary(nsString& aSummary);
   uint32_t TableColumnCount();
   uint32_t TableRowCount();
   ProxyAccessible* TableCellAt(uint32_t aRow, uint32_t aCol);
--- a/accessible/mac/moz.build
+++ b/accessible/mac/moz.build
@@ -35,9 +35,11 @@ LOCAL_INCLUDES += [
     '/layout/generic',
     '/layout/xul',
     '/widget',
     '/widget/cocoa',
 ]
 
 FINAL_LIBRARY = 'xul'
 
+include('/ipc/chromium/chromium-config.mozbuild')
+
 FAIL_ON_WARNINGS = True
--- a/accessible/mac/mozAccessible.mm
+++ b/accessible/mac/mozAccessible.mm
@@ -13,16 +13,17 @@
 #include "nsIAccessibleRelation.h"
 #include "nsIAccessibleEditableText.h"
 #include "nsIPersistentProperties2.h"
 #include "Relation.h"
 #include "Role.h"
 #include "RootAccessible.h"
 #include "TableAccessible.h"
 #include "TableCellAccessible.h"
+#include "mozilla/a11y/PDocAccessible.h"
 
 #include "mozilla/Services.h"
 #include "nsRect.h"
 #include "nsCocoaUtils.h"
 #include "nsCoord.h"
 #include "nsObjCExceptions.h"
 #include "nsWhitespaceTokenizer.h"
 #include <prdtoa.h>
@@ -365,17 +366,18 @@ ConvertToNSArray(nsTArray<ProxyAccessibl
   NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
 }
 
 - (id)accessibilityAttributeValue:(NSString*)attribute
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
 
   AccessibleWrap* accWrap = [self getGeckoAccessible];
-  if (!accWrap)
+  ProxyAccessible* proxy = [self getProxyAccessible];
+  if (!accWrap && !proxy)
     return nil;
 
 #if DEBUG
   if ([attribute isEqualToString:@"AXMozDescription"])
     return [NSString stringWithFormat:@"role = %u native = %@", mRole, [self class]];
 #endif
 
   if ([attribute isEqualToString:NSAccessibilityChildrenAttribute])
@@ -407,72 +409,127 @@ ConvertToNSArray(nsTArray<ProxyAccessibl
     return [self size];
   if ([attribute isEqualToString:NSAccessibilityWindowAttribute])
     return [self window];
   if ([attribute isEqualToString:NSAccessibilityTopLevelUIElementAttribute])
     return [self window];
   if ([attribute isEqualToString:NSAccessibilityTitleAttribute])
     return [self title];
   if ([attribute isEqualToString:NSAccessibilityTitleUIElementAttribute]) {
-    Relation rel =
-      accWrap->RelationByType(RelationType::LABELLED_BY);
-    Accessible* tempAcc = rel.Next();
-    return tempAcc ? GetNativeFromGeckoAccessible(tempAcc) : nil;
+    if (accWrap) {
+      Relation rel = accWrap->RelationByType(RelationType::LABELLED_BY);
+      Accessible* tempAcc = rel.Next();
+      return tempAcc ? GetNativeFromGeckoAccessible(tempAcc) : nil;
+    }
+    nsTArray<ProxyAccessible*> rel = proxy->RelationByType(RelationType::LABELLED_BY);
+    ProxyAccessible* tempProxy = rel.SafeElementAt(0);
+    return tempProxy ? GetNativeFromProxy(tempProxy) : nil;
   }
   if ([attribute isEqualToString:NSAccessibilityHelpAttribute])
     return [self help];
 
-  if (accWrap->IsTable()) {
-    TableAccessible* table = accWrap->AsTable();
-    if ([attribute isEqualToString:NSAccessibilityRowCountAttribute])
-      return @(table->RowCount());
-    if ([attribute isEqualToString:NSAccessibilityColumnCountAttribute])
-      return @(table->ColCount());
-    if ([attribute isEqualToString:NSAccessibilityRowsAttribute]) {
-      // Create a new array with the list of table rows.
-      NSMutableArray* nativeArray = [[NSMutableArray alloc] init];
-      uint32_t totalCount = accWrap->ChildCount();
-      for (uint32_t i = 0; i < totalCount; i++) {
-        if (accWrap->GetChildAt(i)->IsTableRow()) {
-          mozAccessible* curNative =
-            GetNativeFromGeckoAccessible(accWrap->GetChildAt(i));
-          if (curNative)
-            [nativeArray addObject:GetObjectOrRepresentedView(curNative)];
+  if (accWrap) {
+    if (accWrap->IsTable()) {
+      TableAccessible* table = accWrap->AsTable();
+      if ([attribute isEqualToString:NSAccessibilityRowCountAttribute])
+        return @(table->RowCount());
+      if ([attribute isEqualToString:NSAccessibilityColumnCountAttribute])
+        return @(table->ColCount());
+      if ([attribute isEqualToString:NSAccessibilityRowsAttribute]) {
+        // Create a new array with the list of table rows.
+        NSMutableArray* nativeArray = [[NSMutableArray alloc] init];
+        uint32_t totalCount = accWrap->ChildCount();
+        for (uint32_t i = 0; i < totalCount; i++) {
+          if (accWrap->GetChildAt(i)->IsTableRow()) {
+            mozAccessible* curNative =
+              GetNativeFromGeckoAccessible(accWrap->GetChildAt(i));
+            if (curNative)
+              [nativeArray addObject:GetObjectOrRepresentedView(curNative)];
+          }
         }
+        return nativeArray;
       }
-      return nativeArray;
+    } else if (accWrap->IsTableRow()) {
+      if ([attribute isEqualToString:NSAccessibilityIndexAttribute]) {
+        // Count the number of rows before that one to obtain the row index.
+        uint32_t index = 0;
+        for (int32_t i = accWrap->IndexInParent() - 1; i >= 0; i--) {
+          if (accWrap->GetChildAt(i)->IsTableRow()) {
+            index++;
+          }
+        }
+        return [NSNumber numberWithUnsignedInteger:index];
+      }
+    } else if (accWrap->IsTableCell()) {
+      TableCellAccessible* cell = accWrap->AsTableCell();
+      if ([attribute isEqualToString:NSAccessibilityRowIndexRangeAttribute])
+        return [NSValue valueWithRange:NSMakeRange(cell->RowIdx(),
+                                                   cell->RowExtent())];
+      if ([attribute isEqualToString:NSAccessibilityColumnIndexRangeAttribute])
+        return [NSValue valueWithRange:NSMakeRange(cell->ColIdx(),
+                                                   cell->ColExtent())];
+      if ([attribute isEqualToString:NSAccessibilityRowHeaderUIElementsAttribute]) {
+        nsAutoTArray<Accessible*, 10> headerCells;
+        cell->RowHeaderCells(&headerCells);
+        return ConvertToNSArray(headerCells);
+      }
+      if ([attribute isEqualToString:NSAccessibilityColumnHeaderUIElementsAttribute]) {
+        nsAutoTArray<Accessible*, 10> headerCells;
+        cell->ColHeaderCells(&headerCells);
+        return ConvertToNSArray(headerCells);
+      }
     }
-  } else if (accWrap->IsTableRow()) {
-    if ([attribute isEqualToString:NSAccessibilityIndexAttribute]) {
-      // Count the number of rows before that one to obtain the row index.
-      uint32_t index = 0;
-      for (int32_t i = accWrap->IndexInParent() - 1; i >= 0; i--) {
-        if (accWrap->GetChildAt(i)->IsTableRow()) {
-          index++;
+  } else if (proxy) {
+    if (proxy->IsTable()) {
+      if ([attribute isEqualToString:NSAccessibilityRowCountAttribute])
+        return @(proxy->TableRowCount());
+      if ([attribute isEqualToString:NSAccessibilityColumnCountAttribute])
+        return @(proxy->TableColumnCount());
+      if ([attribute isEqualToString:NSAccessibilityRowsAttribute]) {
+        // Create a new array with the list of table rows.
+        NSMutableArray* nativeArray = [[NSMutableArray alloc] init];
+        uint32_t totalCount = proxy->ChildrenCount();
+        for (uint32_t i = 0; i < totalCount; i++) {
+          if (proxy->ChildAt(i)->IsTableRow()) {
+            mozAccessible* curNative =
+              GetNativeFromProxy(proxy->ChildAt(i));
+            if (curNative)
+              [nativeArray addObject:GetObjectOrRepresentedView(curNative)];
+          }
         }
+        return nativeArray;
       }
-      return [NSNumber numberWithUnsignedInteger:index];
-    }
-  } else if (accWrap->IsTableCell()) {
-    TableCellAccessible* cell = accWrap->AsTableCell();
-    if ([attribute isEqualToString:NSAccessibilityRowIndexRangeAttribute])
-      return [NSValue valueWithRange:NSMakeRange(cell->RowIdx(),
-                                                 cell->RowExtent())];
-    if ([attribute isEqualToString:NSAccessibilityColumnIndexRangeAttribute])
-      return [NSValue valueWithRange:NSMakeRange(cell->ColIdx(),
-                                                 cell->ColExtent())];
-    if ([attribute isEqualToString:NSAccessibilityRowHeaderUIElementsAttribute]) {
-      nsAutoTArray<Accessible*, 10> headerCells;
-      cell->RowHeaderCells(&headerCells);
-      return ConvertToNSArray(headerCells);
-    }
-    if ([attribute isEqualToString:NSAccessibilityColumnHeaderUIElementsAttribute]) {
-      nsAutoTArray<Accessible*, 10> headerCells;
-      cell->ColHeaderCells(&headerCells);
-      return ConvertToNSArray(headerCells);
+    } else if (proxy->IsTableRow()) {
+      if ([attribute isEqualToString:NSAccessibilityIndexAttribute]) {
+        // Count the number of rows before that one to obtain the row index.
+        uint32_t index = 0;
+        for (int32_t i = proxy->IndexInParent() - 1; i >= 0; i--) {
+          if (proxy->ChildAt(i)->IsTableRow()) {
+            index++;
+          }
+        }
+        return [NSNumber numberWithUnsignedInteger:index];
+      }
+    } else if (proxy->IsTableCell()) {
+      if ([attribute isEqualToString:NSAccessibilityRowIndexRangeAttribute])
+        return [NSValue valueWithRange:NSMakeRange(proxy->RowIdx(),
+                                                   proxy->RowExtent())];
+      if ([attribute isEqualToString:NSAccessibilityColumnIndexRangeAttribute])
+        return [NSValue valueWithRange:NSMakeRange(proxy->ColIdx(),
+                                                   proxy->ColExtent())];
+      if ([attribute isEqualToString:NSAccessibilityRowHeaderUIElementsAttribute]) {
+        nsTArray<ProxyAccessible*> headerCells;
+        proxy->RowHeaderCells(&headerCells);
+        return ConvertToNSArray(headerCells);
+      }
+      if ([attribute isEqualToString:NSAccessibilityColumnHeaderUIElementsAttribute]) {
+        nsTArray<ProxyAccessible*> headerCells;
+        proxy->ColHeaderCells(&headerCells);
+        return ConvertToNSArray(headerCells);
+      }
     }
   }
 
   switch (mRole) {
   case roles::MATHML_ROOT:
     if ([attribute isEqualToString:NSAccessibilityMathRootRadicandAttribute])
       return [self childAt:0];
     if ([attribute isEqualToString:NSAccessibilityMathRootIndexAttribute])
@@ -491,19 +548,30 @@ ConvertToNSArray(nsTArray<ProxyAccessibl
       // WebKit sets line thickness to some logical value parsed in the
       // renderer object of the <mfrac> element. It's not clear whether the
       // exact value is relevant to assistive technologies. From a semantic
       // point of view, the only important point is to distinguish between
       // <mfrac> elements that have a fraction bar and those that do not.
       // Per the MathML 3 spec, the latter happens iff the linethickness
       // attribute is of the form [zero-float][optional-unit]. In that case we
       // set line thickness to zero and in the other cases we set it to one.
-      nsCOMPtr<nsIPersistentProperties> attributes = accWrap->Attributes();
       nsAutoString thickness;
-      nsAccUtils::GetAccAttr(attributes, nsGkAtoms::linethickness_, thickness);
+      if (accWrap) {
+        nsCOMPtr<nsIPersistentProperties> attributes = accWrap->Attributes();
+        nsAccUtils::GetAccAttr(attributes, nsGkAtoms::linethickness_, thickness);
+      } else {
+        nsAutoTArray<Attribute, 10> attrs;
+        proxy->Attributes(&attrs);
+        for (size_t i = 0 ; i < attrs.Length() ; i++) {
+          if (attrs.ElementAt(i).Name() == "thickness") {
+            thickness = attrs.ElementAt(i).Value();
+            break;
+          }
+        }
+      }
       double value = 1.0;
       if (!thickness.IsEmpty())
         value = PR_strtod(NS_LossyConvertUTF16toASCII(thickness).get(),
                           nullptr);
       return [NSNumber numberWithInteger:(value ? 1 : 0)];
     }
     break;
   case roles::MATHML_SUB: