ia2AccessibleHypertext.cpp (3897B)
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 "ia2AccessibleHypertext.h" 9 10 #include "AccessibleHypertext_i.c" 11 #include "AccessibleHypertext2_i.c" 12 13 #include "mozilla/a11y/HyperTextAccessibleBase.h" 14 15 #include "IUnknownImpl.h" 16 17 using namespace mozilla::a11y; 18 19 HyperTextAccessibleBase* ia2AccessibleHypertext::TextAcc() { 20 Accessible* acc = Acc(); 21 return acc ? acc->AsHyperTextBase() : nullptr; 22 } 23 24 // IUnknown 25 STDMETHODIMP 26 ia2AccessibleHypertext::QueryInterface(REFIID aIID, void** aInstancePtr) { 27 if (!aInstancePtr) return E_FAIL; 28 29 *aInstancePtr = nullptr; 30 31 Accessible* acc = Acc(); 32 if (acc && acc->IsTextRole()) { 33 if (aIID == IID_IAccessibleText) { 34 *aInstancePtr = 35 static_cast<IAccessibleText*>(static_cast<ia2AccessibleText*>(this)); 36 } else if (aIID == IID_IAccessibleHypertext) { 37 *aInstancePtr = static_cast<IAccessibleHypertext*>(this); 38 } else if (aIID == IID_IAccessibleHypertext2) { 39 *aInstancePtr = static_cast<IAccessibleHypertext2*>(this); 40 } else if (aIID == IID_IAccessibleEditableText) { 41 *aInstancePtr = static_cast<IAccessibleEditableText*>(this); 42 } else if (aIID == IID_IAccessibleTextSelectionContainer) { 43 *aInstancePtr = static_cast<IAccessibleTextSelectionContainer*>(this); 44 } 45 46 if (*aInstancePtr) { 47 AddRef(); 48 return S_OK; 49 } 50 } 51 52 return MsaaAccessible::QueryInterface(aIID, aInstancePtr); 53 } 54 55 // IAccessibleHypertext 56 57 STDMETHODIMP 58 ia2AccessibleHypertext::get_nHyperlinks(long* aHyperlinkCount) { 59 if (!aHyperlinkCount) return E_INVALIDARG; 60 61 *aHyperlinkCount = 0; 62 63 HyperTextAccessibleBase* hyperText = TextAcc(); 64 if (!hyperText) return CO_E_OBJNOTCONNECTED; 65 66 *aHyperlinkCount = hyperText->LinkCount(); 67 return S_OK; 68 } 69 70 STDMETHODIMP 71 ia2AccessibleHypertext::get_hyperlink(long aLinkIndex, 72 IAccessibleHyperlink** aHyperlink) { 73 if (!aHyperlink) return E_INVALIDARG; 74 75 *aHyperlink = nullptr; 76 77 HyperTextAccessibleBase* hyperText = TextAcc(); 78 if (!hyperText) { 79 return CO_E_OBJNOTCONNECTED; 80 } 81 82 Accessible* hyperLink = hyperText->LinkAt(aLinkIndex); 83 84 if (!hyperLink) return E_FAIL; 85 86 RefPtr<IAccessibleHyperlink> result = MsaaAccessible::GetFrom(hyperLink); 87 result.forget(aHyperlink); 88 return S_OK; 89 } 90 91 STDMETHODIMP 92 ia2AccessibleHypertext::get_hyperlinkIndex(long aCharIndex, 93 long* aHyperlinkIndex) { 94 if (!aHyperlinkIndex) return E_INVALIDARG; 95 96 *aHyperlinkIndex = 0; 97 98 HyperTextAccessibleBase* hyperAcc = TextAcc(); 99 if (!hyperAcc) return CO_E_OBJNOTCONNECTED; 100 101 *aHyperlinkIndex = hyperAcc->LinkIndexAtOffset(aCharIndex); 102 return S_OK; 103 } 104 105 STDMETHODIMP 106 ia2AccessibleHypertext::get_hyperlinks(IAccessibleHyperlink*** aHyperlinks, 107 long* aNHyperlinks) { 108 if (!aHyperlinks || !aNHyperlinks) { 109 return E_INVALIDARG; 110 } 111 112 *aHyperlinks = nullptr; 113 *aNHyperlinks = 0; 114 115 HyperTextAccessibleBase* hyperText = TextAcc(); 116 if (!hyperText) { 117 return CO_E_OBJNOTCONNECTED; 118 } 119 120 uint32_t count = hyperText->LinkCount(); 121 *aNHyperlinks = count; 122 123 if (count == 0) { 124 *aHyperlinks = nullptr; 125 return S_FALSE; 126 } 127 128 *aHyperlinks = static_cast<IAccessibleHyperlink**>( 129 ::CoTaskMemAlloc(sizeof(IAccessibleHyperlink*) * count)); 130 if (!*aHyperlinks) { 131 return E_OUTOFMEMORY; 132 } 133 134 for (uint32_t i = 0; i < count; ++i) { 135 Accessible* hyperLink = hyperText->LinkAt(i); 136 MOZ_ASSERT(hyperLink); 137 RefPtr<IAccessibleHyperlink> iaHyper = MsaaAccessible::GetFrom(hyperLink); 138 iaHyper.forget(&(*aHyperlinks)[i]); 139 } 140 141 return S_OK; 142 }