ia2AccessibleHyperlink.cpp (3672B)
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 8 #include "ia2AccessibleHyperlink.h" 9 10 #include "AccessibleHyperlink.h" 11 #include "AccessibleHyperlink_i.c" 12 13 #include "AccessibleWrap.h" 14 #include "IUnknownImpl.h" 15 #include "MsaaAccessible.h" 16 #include "nsIURI.h" 17 18 using namespace mozilla::a11y; 19 20 Accessible* ia2AccessibleHyperlink::Acc() { 21 return static_cast<MsaaAccessible*>(this)->Acc(); 22 } 23 24 AccessibleWrap* ia2AccessibleHyperlink::LocalAcc() { 25 return static_cast<MsaaAccessible*>(this)->LocalAcc(); 26 } 27 28 // IUnknown 29 30 STDMETHODIMP 31 ia2AccessibleHyperlink::QueryInterface(REFIID iid, void** ppv) { 32 if (!ppv) return E_INVALIDARG; 33 34 *ppv = nullptr; 35 36 if (IID_IAccessibleHyperlink == iid) { 37 Accessible* acc = Acc(); 38 if (!acc || !acc->IsLink()) { 39 return E_NOINTERFACE; 40 } 41 42 *ppv = static_cast<IAccessibleHyperlink*>(this); 43 (reinterpret_cast<IUnknown*>(*ppv))->AddRef(); 44 return S_OK; 45 } 46 47 return ia2AccessibleAction::QueryInterface(iid, ppv); 48 } 49 50 // IAccessibleHyperlink 51 52 STDMETHODIMP 53 ia2AccessibleHyperlink::get_anchor(long aIndex, VARIANT* aAnchor) { 54 if (!aAnchor) return E_INVALIDARG; 55 56 VariantInit(aAnchor); 57 58 Accessible* thisObj = Acc(); 59 if (!thisObj) { 60 return CO_E_OBJNOTCONNECTED; 61 } 62 63 if (aIndex < 0 || aIndex >= static_cast<long>(thisObj->AnchorCount())) 64 return E_INVALIDARG; 65 66 if (!thisObj->IsLink()) return S_FALSE; 67 68 Accessible* anchor = thisObj->AnchorAt(aIndex); 69 if (!anchor) return S_FALSE; 70 71 RefPtr<IAccessible> result = MsaaAccessible::GetFrom(anchor); 72 result.forget(&aAnchor->punkVal); 73 aAnchor->vt = VT_UNKNOWN; 74 return S_OK; 75 } 76 77 STDMETHODIMP 78 ia2AccessibleHyperlink::get_anchorTarget(long aIndex, VARIANT* aAnchorTarget) { 79 if (!aAnchorTarget) { 80 return E_INVALIDARG; 81 } 82 83 VariantInit(aAnchorTarget); 84 85 Accessible* thisObj = Acc(); 86 if (!thisObj) { 87 return CO_E_OBJNOTCONNECTED; 88 } 89 nsAutoCString uriStr; 90 91 if (aIndex < 0 || aIndex >= static_cast<long>(thisObj->AnchorCount())) { 92 return E_INVALIDARG; 93 } 94 95 if (!thisObj->IsLink()) { 96 return S_FALSE; 97 } 98 99 nsCOMPtr<nsIURI> uri = thisObj->AnchorURIAt(aIndex); 100 if (!uri) { 101 return S_FALSE; 102 } 103 104 nsresult rv = uri->GetSpec(uriStr); 105 if (NS_FAILED(rv)) { 106 return GetHRESULT(rv); 107 } 108 109 nsAutoString stringURI; 110 AppendUTF8toUTF16(uriStr, stringURI); 111 112 aAnchorTarget->vt = VT_BSTR; 113 aAnchorTarget->bstrVal = 114 ::SysAllocStringLen(stringURI.get(), stringURI.Length()); 115 return aAnchorTarget->bstrVal ? S_OK : E_OUTOFMEMORY; 116 } 117 118 STDMETHODIMP 119 ia2AccessibleHyperlink::get_startIndex(long* aIndex) { 120 if (!aIndex) return E_INVALIDARG; 121 122 *aIndex = 0; 123 124 Accessible* thisObj = Acc(); 125 if (!thisObj) { 126 return CO_E_OBJNOTCONNECTED; 127 } 128 129 if (!thisObj->IsLink()) return S_FALSE; 130 131 *aIndex = thisObj->StartOffset(); 132 return S_OK; 133 } 134 135 STDMETHODIMP 136 ia2AccessibleHyperlink::get_endIndex(long* aIndex) { 137 if (!aIndex) return E_INVALIDARG; 138 139 *aIndex = 0; 140 141 Accessible* thisObj = Acc(); 142 if (!thisObj) { 143 return CO_E_OBJNOTCONNECTED; 144 } 145 146 if (!thisObj->IsLink()) return S_FALSE; 147 148 *aIndex = thisObj->EndOffset(); 149 return S_OK; 150 } 151 152 STDMETHODIMP 153 ia2AccessibleHyperlink::get_valid(boolean* aValid) { 154 if (!aValid) return E_INVALIDARG; 155 156 *aValid = false; 157 158 Accessible* thisObj = Acc(); 159 if (!thisObj) { 160 return CO_E_OBJNOTCONNECTED; 161 } 162 163 if (!thisObj->IsLink()) return S_FALSE; 164 165 *aValid = thisObj->IsLinkValid(); 166 return S_OK; 167 }