ia2AccessibleHyperlink.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /* vim:expandtab:shiftwidth=2:tabstop=2:
  3. */
  4. /* This Source Code Form is subject to the terms of the Mozilla Public
  5. * License, v. 2.0. If a copy of the MPL was not distributed with this
  6. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  7. #include "Accessible2.h"
  8. #include "AccessibleHyperlink.h"
  9. #include "AccessibleHyperlink_i.c"
  10. #include "AccessibleWrap.h"
  11. #include "IUnknownImpl.h"
  12. #include "nsIURI.h"
  13. using namespace mozilla::a11y;
  14. // IUnknown
  15. STDMETHODIMP
  16. ia2AccessibleHyperlink::QueryInterface(REFIID iid, void** ppv)
  17. {
  18. if (!ppv)
  19. return E_INVALIDARG;
  20. *ppv = nullptr;
  21. if (IID_IAccessibleHyperlink == iid) {
  22. auto accWrap = static_cast<AccessibleWrap*>(this);
  23. if (accWrap->IsProxy() ?
  24. !(accWrap->ProxyInterfaces() & Interfaces::HYPERLINK) :
  25. !accWrap->IsLink())
  26. return E_NOINTERFACE;
  27. *ppv = static_cast<IAccessibleHyperlink*>(this);
  28. (reinterpret_cast<IUnknown*>(*ppv))->AddRef();
  29. return S_OK;
  30. }
  31. return ia2AccessibleAction::QueryInterface(iid, ppv);
  32. }
  33. // IAccessibleHyperlink
  34. STDMETHODIMP
  35. ia2AccessibleHyperlink::get_anchor(long aIndex, VARIANT* aAnchor)
  36. {
  37. if (!aAnchor)
  38. return E_INVALIDARG;
  39. VariantInit(aAnchor);
  40. Accessible* thisObj = static_cast<AccessibleWrap*>(this);
  41. MOZ_ASSERT(!thisObj->IsProxy());
  42. if (thisObj->IsDefunct())
  43. return CO_E_OBJNOTCONNECTED;
  44. if (aIndex < 0 || aIndex >= static_cast<long>(thisObj->AnchorCount()))
  45. return E_INVALIDARG;
  46. if (!thisObj->IsLink())
  47. return S_FALSE;
  48. AccessibleWrap* anchor =
  49. static_cast<AccessibleWrap*>(thisObj->AnchorAt(aIndex));
  50. if (!anchor)
  51. return S_FALSE;
  52. void* instancePtr = nullptr;
  53. HRESULT result = anchor->QueryInterface(IID_IUnknown, &instancePtr);
  54. if (FAILED(result))
  55. return result;
  56. aAnchor->punkVal = static_cast<IUnknown*>(instancePtr);
  57. aAnchor->vt = VT_UNKNOWN;
  58. return S_OK;
  59. }
  60. STDMETHODIMP
  61. ia2AccessibleHyperlink::get_anchorTarget(long aIndex, VARIANT* aAnchorTarget)
  62. {
  63. if (!aAnchorTarget) {
  64. return E_INVALIDARG;
  65. }
  66. VariantInit(aAnchorTarget);
  67. Accessible* thisObj = static_cast<AccessibleWrap*>(this);
  68. nsAutoCString uriStr;
  69. MOZ_ASSERT(!thisObj->IsProxy());
  70. if (thisObj->IsDefunct()) {
  71. return CO_E_OBJNOTCONNECTED;
  72. }
  73. if (aIndex < 0 || aIndex >= static_cast<long>(thisObj->AnchorCount())) {
  74. return E_INVALIDARG;
  75. }
  76. if (!thisObj->IsLink()) {
  77. return S_FALSE;
  78. }
  79. nsCOMPtr<nsIURI> uri = thisObj->AnchorURIAt(aIndex);
  80. if (!uri) {
  81. return S_FALSE;
  82. }
  83. nsresult rv = uri->GetSpec(uriStr);
  84. if (NS_FAILED(rv)) {
  85. return GetHRESULT(rv);
  86. }
  87. nsAutoString stringURI;
  88. AppendUTF8toUTF16(uriStr, stringURI);
  89. aAnchorTarget->vt = VT_BSTR;
  90. aAnchorTarget->bstrVal = ::SysAllocStringLen(stringURI.get(),
  91. stringURI.Length());
  92. return aAnchorTarget->bstrVal ? S_OK : E_OUTOFMEMORY;
  93. }
  94. STDMETHODIMP
  95. ia2AccessibleHyperlink::get_startIndex(long* aIndex)
  96. {
  97. if (!aIndex)
  98. return E_INVALIDARG;
  99. *aIndex = 0;
  100. MOZ_ASSERT(!HyperTextProxyFor(this));
  101. Accessible* thisObj = static_cast<AccessibleWrap*>(this);
  102. if (thisObj->IsDefunct())
  103. return CO_E_OBJNOTCONNECTED;
  104. if (!thisObj->IsLink())
  105. return S_FALSE;
  106. *aIndex = thisObj->StartOffset();
  107. return S_OK;
  108. }
  109. STDMETHODIMP
  110. ia2AccessibleHyperlink::get_endIndex(long* aIndex)
  111. {
  112. if (!aIndex)
  113. return E_INVALIDARG;
  114. *aIndex = 0;
  115. MOZ_ASSERT(!HyperTextProxyFor(this));
  116. Accessible* thisObj = static_cast<AccessibleWrap*>(this);
  117. if (thisObj->IsDefunct())
  118. return CO_E_OBJNOTCONNECTED;
  119. if (!thisObj->IsLink())
  120. return S_FALSE;
  121. *aIndex = thisObj->EndOffset();
  122. return S_OK;
  123. }
  124. STDMETHODIMP
  125. ia2AccessibleHyperlink::get_valid(boolean* aValid)
  126. {
  127. if (!aValid)
  128. return E_INVALIDARG;
  129. *aValid = false;
  130. MOZ_ASSERT(!HyperTextProxyFor(this));
  131. Accessible* thisObj = static_cast<AccessibleWrap*>(this);
  132. if (thisObj->IsDefunct())
  133. return CO_E_OBJNOTCONNECTED;
  134. if (!thisObj->IsLink())
  135. return S_FALSE;
  136. *aValid = thisObj->IsLinkValid();
  137. return S_OK;
  138. }