bug 1303447 - implement text interface methods for the windows ProxyAccessible r=aklotz
authorMichael Li <michael.li11702@gmail.com>
Tue, 18 Oct 2016 10:13:10 -0400
changeset 319763 d1e487f723a0154cbd9752f37fcbaebf17cbcf1c
parent 319762 81a257aa9c4e194750afb65dd666ea600981d99a
child 319764 582e5f96a727af4a6da4ec26dbe882ef57914bfb
push id83244
push usertsaunders@mozilla.com
push dateThu, 27 Oct 2016 22:02:44 +0000
treeherdermozilla-inbound@d1e487f723a0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersaklotz
bugs1303447
milestone52.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 1303447 - implement text interface methods for the windows ProxyAccessible r=aklotz
accessible/ipc/win/ProxyAccessible.cpp
accessible/xpcom/xpcAccessibleHyperText.cpp
--- a/accessible/ipc/win/ProxyAccessible.cpp
+++ b/accessible/ipc/win/ProxyAccessible.cpp
@@ -56,16 +56,22 @@ ProxyAccessible::GetCOMInterface(void** 
 template<typename Interface> struct InterfaceIID {};
 
 template<>
 struct InterfaceIID<IAccessibleValue>
 {
   static REFIID Value() { return IID_IAccessibleValue; }
 };
 
+template<>
+struct InterfaceIID<IAccessibleText>
+{
+  static REFIID Value() { return IID_IAccessibleText; }
+};
+
 /**
  * Get the COM proxy for this proxy accessible and QueryInterface it with the
  * correct IID
  */
 template<typename Interface>
 static already_AddRefed<Interface>
 QueryInterface(const ProxyAccessible* aProxy)
 {
@@ -373,10 +379,221 @@ ProxyAccessible::MaxValue()
   HRESULT hr = acc->get_maximumValue(&maximumValue);
   if (FAILED(hr) || maximumValue.vt != VT_R8) {
     return UnspecifiedNaN<double>();
   }
 
   return maximumValue.dblVal;
 }
 
+static IA2TextBoundaryType
+GetIA2TextBoundary(AccessibleTextBoundary aGeckoBoundaryType)
+{
+  switch (aGeckoBoundaryType) {
+    case nsIAccessibleText::BOUNDARY_CHAR:
+      return IA2_TEXT_BOUNDARY_CHAR;
+    case nsIAccessibleText::BOUNDARY_WORD_START:
+      return IA2_TEXT_BOUNDARY_WORD;
+    case nsIAccessibleText::BOUNDARY_LINE_START:
+      return IA2_TEXT_BOUNDARY_LINE;
+    default:
+      MOZ_RELEASE_ASSERT(false);
+  }
+}
+
+bool
+ProxyAccessible::TextSubstring(int32_t aStartOffset, int32_t aEndOffset,
+                               nsString& aText) const
+{
+  RefPtr<IAccessibleText> acc = QueryInterface<IAccessibleText>(this);
+  if (!acc) {
+    return false;
+  }
+
+  BSTR result;
+  HRESULT hr = acc->get_text(static_cast<long>(aStartOffset),
+                             static_cast<long>(aEndOffset), &result);
+  if (FAILED(hr)) {
+    return false;
+  }
+
+  _bstr_t resultWrap(result, false);
+  aText = (wchar_t*)result;
+
+  return true;
+}
+
+void
+ProxyAccessible::GetTextBeforeOffset(int32_t aOffset,
+                                    AccessibleTextBoundary aBoundaryType,
+                                    nsString& aText, int32_t* aStartOffset,
+                                    int32_t* aEndOffset)
+{
+  RefPtr<IAccessibleText> acc = QueryInterface<IAccessibleText>(this);
+  if (!acc) {
+    return;
+  }
+
+  BSTR result;
+  long start, end;
+  HRESULT hr = acc->get_textBeforeOffset(aOffset,
+                                         GetIA2TextBoundary(aBoundaryType),
+                                         &start, &end, &result);
+  if (FAILED(hr)) {
+    return;
+  }
+
+  _bstr_t resultWrap(result, false);
+  *aStartOffset = start;
+  *aEndOffset = end;
+  aText = (wchar_t*)result;
+}
+
+void
+ProxyAccessible::GetTextAfterOffset(int32_t aOffset,
+                                    AccessibleTextBoundary aBoundaryType,
+                                    nsString& aText, int32_t* aStartOffset,
+                                    int32_t* aEndOffset)
+{
+  RefPtr<IAccessibleText> acc = QueryInterface<IAccessibleText>(this);
+  if (!acc) {
+    return;
+  }
+
+  BSTR result;
+  long start, end;
+  HRESULT hr = acc->get_textAfterOffset(aOffset,
+                                        GetIA2TextBoundary(aBoundaryType),
+                                        &start, &end, &result);
+  if (FAILED(hr)) {
+    return;
+  }
+
+  _bstr_t resultWrap(result, false);
+  aText = (wchar_t*)result;
+  *aStartOffset = start;
+  *aEndOffset = end;
+}
+
+void
+ProxyAccessible::GetTextAtOffset(int32_t aOffset,
+                                    AccessibleTextBoundary aBoundaryType,
+                                    nsString& aText, int32_t* aStartOffset,
+                                    int32_t* aEndOffset)
+{
+  RefPtr<IAccessibleText> acc = QueryInterface<IAccessibleText>(this);
+  if (!acc) {
+    return;
+  }
+
+  BSTR result;
+  long start, end;
+  HRESULT hr = acc->get_textAtOffset(aOffset, GetIA2TextBoundary(aBoundaryType),
+                                     &start, &end, &result);
+  if (FAILED(hr)) {
+    return;
+  }
+
+  _bstr_t resultWrap(result, false);
+  aText = (wchar_t*)result;
+  *aStartOffset = start;
+  *aEndOffset = end;
+}
+
+bool
+ProxyAccessible::AddToSelection(int32_t aStartOffset, int32_t aEndOffset)
+{
+  RefPtr<IAccessibleText> acc = QueryInterface<IAccessibleText>(this);
+  if (!acc) {
+    return false;
+  }
+
+  return SUCCEEDED(acc->addSelection(static_cast<long>(aStartOffset),
+                                     static_cast<long>(aEndOffset)));
+}
+
+bool
+ProxyAccessible::RemoveFromSelection(int32_t aSelectionNum)
+{
+  RefPtr<IAccessibleText> acc = QueryInterface<IAccessibleText>(this);
+  if (!acc) {
+    return false;
+  }
+
+  return SUCCEEDED(acc->removeSelection(static_cast<long>(aSelectionNum)));
+}
+
+int32_t
+ProxyAccessible::CaretOffset()
+{
+  RefPtr<IAccessibleText> acc = QueryInterface<IAccessibleText>(this);
+  if (!acc) {
+    return -1;
+  }
+
+  long offset;
+  HRESULT hr = acc->get_caretOffset(&offset);
+  if (FAILED(hr)) {
+    return -1;
+  }
+
+  return static_cast<int32_t>(offset);
+}
+
+void
+ProxyAccessible::SetCaretOffset(int32_t aOffset)
+{
+  RefPtr<IAccessibleText> acc = QueryInterface<IAccessibleText>(this);
+  if (!acc) {
+    return;
+  }
+
+  acc->setCaretOffset(static_cast<long>(aOffset));
+}
+
+/**
+ * aScrollType should be one of the nsIAccessiblescrollType constants.
+ */
+void
+ProxyAccessible::ScrollSubstringTo(int32_t aStartOffset, int32_t aEndOffset,
+                                   uint32_t aScrollType)
+{
+  RefPtr<IAccessibleText> acc = QueryInterface<IAccessibleText>(this);
+  if (!acc) {
+    return;
+  }
+
+  acc->scrollSubstringTo(static_cast<long>(aStartOffset),
+                         static_cast<long>(aEndOffset),
+                         static_cast<IA2ScrollType>(aScrollType));
+}
+
+/**
+ * aCoordinateType is one of the nsIAccessibleCoordinateType constants.
+ */
+void
+ProxyAccessible::ScrollSubstringToPoint(int32_t aStartOffset, int32_t aEndOffset,
+                                        uint32_t aCoordinateType, int32_t aX,
+                                        int32_t aY)
+{
+  RefPtr<IAccessibleText> acc = QueryInterface<IAccessibleText>(this);
+  if (!acc) {
+    return;
+  }
+
+  IA2CoordinateType coordType;
+  if (aCoordinateType == nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE) {
+    coordType = IA2_COORDTYPE_SCREEN_RELATIVE;
+  } else if (aCoordinateType == nsIAccessibleCoordinateType::COORDTYPE_PARENT_RELATIVE) {
+    coordType = IA2_COORDTYPE_PARENT_RELATIVE;
+  } else {
+    MOZ_RELEASE_ASSERT(false, "unsupported coord type");
+  }
+
+  acc->scrollSubstringToPoint(static_cast<long>(aStartOffset),
+                              static_cast<long>(aEndOffset),
+                              coordType,
+                              static_cast<long>(aX),
+                              static_cast<long>(aY));
+}
+
 } // namespace a11y
 } // namespace mozilla
--- a/accessible/xpcom/xpcAccessibleHyperText.cpp
+++ b/accessible/xpcom/xpcAccessibleHyperText.cpp
@@ -63,23 +63,19 @@ xpcAccessibleHyperText::GetText(int32_t 
   aText.Truncate();
 
   if (mIntl.IsNull())
     return NS_ERROR_FAILURE;
 
   if (mIntl.IsAccessible()) {
     Intl()->TextSubstring(aStartOffset, aEndOffset, aText);
   } else {
-#if defined(XP_WIN)
-    return NS_ERROR_NOT_IMPLEMENTED;
-#else
     nsString text;
     mIntl.AsProxy()->TextSubstring(aStartOffset, aEndOffset, text);
     aText = text;
-#endif
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 xpcAccessibleHyperText::GetTextBeforeOffset(int32_t aOffset,
                                             AccessibleTextBoundary aBoundaryType,
                                             int32_t* aStartOffset,
@@ -93,24 +89,20 @@ xpcAccessibleHyperText::GetTextBeforeOff
 
   if (mIntl.IsNull())
     return NS_ERROR_FAILURE;
 
   if (mIntl.IsAccessible()) {
     Intl()->TextBeforeOffset(aOffset, aBoundaryType, aStartOffset, aEndOffset, 
                              aText);
   } else {
-#if defined(XP_WIN)
-    return NS_ERROR_NOT_IMPLEMENTED;
-#else
     nsString text;
     mIntl.AsProxy()->GetTextBeforeOffset(aOffset, aBoundaryType, text,
                                          aStartOffset, aEndOffset);
     aText = text;
-#endif
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 xpcAccessibleHyperText::GetTextAtOffset(int32_t aOffset,
                                         AccessibleTextBoundary aBoundaryType,
                                         int32_t* aStartOffset,
@@ -123,24 +115,20 @@ xpcAccessibleHyperText::GetTextAtOffset(
 
   if (mIntl.IsNull())
     return NS_ERROR_FAILURE;
 
   if (mIntl.IsAccessible()) {
     Intl()->TextAtOffset(aOffset, aBoundaryType, aStartOffset, aEndOffset, 
                          aText);
   } else {
-#if defined(XP_WIN)
-    return NS_ERROR_NOT_IMPLEMENTED;
-#else
     nsString text;
     mIntl.AsProxy()->GetTextAtOffset(aOffset, aBoundaryType, text, 
                                      aStartOffset, aEndOffset);
     aText = text;
-#endif
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 xpcAccessibleHyperText::GetTextAfterOffset(int32_t aOffset,
                                            AccessibleTextBoundary aBoundaryType,
                                            int32_t* aStartOffset,
@@ -153,24 +141,20 @@ xpcAccessibleHyperText::GetTextAfterOffs
 
   if (mIntl.IsNull())
     return NS_ERROR_FAILURE;
 
   if (mIntl.IsAccessible()) {
     Intl()->TextAfterOffset(aOffset, aBoundaryType, aStartOffset, aEndOffset, 
                             aText);
   } else {
-#if defined(XP_WIN)
-    return NS_ERROR_NOT_IMPLEMENTED;
-#else
     nsString text;
     mIntl.AsProxy()->GetTextAfterOffset(aOffset, aBoundaryType, text, 
                                         aStartOffset, aEndOffset);
     aText = text;
-#endif
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 xpcAccessibleHyperText::GetCharacterAtOffset(int32_t aOffset,
                                              char16_t* aCharacter)
 {
@@ -350,39 +334,31 @@ xpcAccessibleHyperText::GetCaretOffset(i
   *aCaretOffset = -1;
 
   if (mIntl.IsNull())
     return NS_ERROR_FAILURE;
 
   if (mIntl.IsAccessible()) {
     *aCaretOffset = Intl()->CaretOffset();
   } else {
-#if defined(XP_WIN)
-    return NS_ERROR_NOT_IMPLEMENTED;
-#else
     *aCaretOffset = mIntl.AsProxy()->CaretOffset();
-#endif
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 xpcAccessibleHyperText::SetCaretOffset(int32_t aCaretOffset)
 {
   if (mIntl.IsNull())
     return NS_ERROR_FAILURE;
 
   if (mIntl.IsAccessible()) {
     Intl()->SetCaretOffset(aCaretOffset);
   } else {
-#if defined(XP_WIN)
-    return NS_ERROR_NOT_IMPLEMENTED;
-#else
     mIntl.AsProxy()->SetCaretOffset(aCaretOffset);
-#endif
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 xpcAccessibleHyperText::GetSelectionCount(int32_t* aSelectionCount)
 {
   NS_ENSURE_ARG_POINTER(aSelectionCount);
@@ -468,59 +444,47 @@ NS_IMETHODIMP
 xpcAccessibleHyperText::AddSelection(int32_t aStartOffset, int32_t aEndOffset)
 {
   if (mIntl.IsNull())
     return NS_ERROR_FAILURE;
 
   if (mIntl.IsAccessible()) {
     Intl()->AddToSelection(aStartOffset, aEndOffset);
   } else {
-#if defined(XP_WIN)
-    return NS_ERROR_NOT_IMPLEMENTED;
-#else
     mIntl.AsProxy()->AddToSelection(aStartOffset, aEndOffset);
-#endif
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 xpcAccessibleHyperText::RemoveSelection(int32_t aSelectionNum)
 {
   if (mIntl.IsNull())
     return NS_ERROR_FAILURE;
 
   if (mIntl.IsAccessible()) {
     Intl()->RemoveFromSelection(aSelectionNum);
   } else {
-#if defined(XP_WIN)
-    return NS_ERROR_NOT_IMPLEMENTED;
-#else
     mIntl.AsProxy()->RemoveFromSelection(aSelectionNum);
-#endif
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 xpcAccessibleHyperText::ScrollSubstringTo(int32_t aStartOffset,
                                           int32_t aEndOffset,
                                           uint32_t aScrollType)
 {
   if (mIntl.IsNull())
     return NS_ERROR_FAILURE;
 
   if (mIntl.IsAccessible()) {
     Intl()->ScrollSubstringTo(aStartOffset, aEndOffset, aScrollType);
   } else {
-#if defined(XP_WIN)
-    return NS_ERROR_NOT_IMPLEMENTED;
-#else
     mIntl.AsProxy()->ScrollSubstringTo(aStartOffset, aEndOffset, aScrollType);
-#endif
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 xpcAccessibleHyperText::ScrollSubstringToPoint(int32_t aStartOffset,
                                                int32_t aEndOffset,
                                                uint32_t aCoordinateType,
@@ -528,22 +492,18 @@ xpcAccessibleHyperText::ScrollSubstringT
 {
   if (mIntl.IsNull())
     return NS_ERROR_FAILURE;
 
   if (mIntl.IsAccessible()) {
     Intl()->ScrollSubstringToPoint(aStartOffset, aEndOffset, aCoordinateType,
                                    aX, aY);
   } else {
-#if defined(XP_WIN)
-    return NS_ERROR_NOT_IMPLEMENTED;
-#else
     mIntl.AsProxy()->ScrollSubstringToPoint(aStartOffset, aEndOffset,
                                             aCoordinateType, aX, aY);
-#endif
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 xpcAccessibleHyperText::GetEnclosingRange(nsIAccessibleTextRange** aRange)
 {
   NS_ENSURE_ARG_POINTER(aRange);