sdnAccessible.cpp (5632B)
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "sdnAccessible.h" 8 9 #include "ISimpleDOM_i.c" 10 #include "mozilla/a11y/RemoteAccessible.h" 11 #include "mozilla/dom/Element.h" 12 13 using namespace mozilla; 14 using namespace mozilla::a11y; 15 16 sdnAccessible::~sdnAccessible() = default; 17 18 IMPL_IUNKNOWN_QUERY_HEAD(sdnAccessible) 19 IMPL_IUNKNOWN_QUERY_IFACE(ISimpleDOMNode) 20 IMPL_IUNKNOWN_QUERY_TAIL_AGGREGATED(mMsaa) 21 22 STDMETHODIMP 23 sdnAccessible::get_nodeInfo(BSTR __RPC_FAR* aNodeName, 24 short __RPC_FAR* aNameSpaceID, 25 BSTR __RPC_FAR* aNodeValue, 26 unsigned int __RPC_FAR* aNumChildren, 27 unsigned int __RPC_FAR* aUniqueID, 28 unsigned short __RPC_FAR* aNodeType) { 29 if (!aNodeName || !aNameSpaceID || !aNodeValue || !aNumChildren || 30 !aUniqueID || !aNodeType) 31 return E_INVALIDARG; 32 33 *aNodeName = nullptr; 34 *aNameSpaceID = 0; 35 *aNodeValue = nullptr; 36 *aNumChildren = 0; 37 *aUniqueID = 0; 38 *aNodeType = 0; 39 40 Accessible* acc = mMsaa->Acc(); 41 if (!acc) { 42 return CO_E_OBJNOTCONNECTED; 43 } 44 45 // This is a unique ID for every content node. The 3rd party accessibility 46 // application can compare this to the childID we return for events such as 47 // focus events, to correlate back to data nodes in their internal object 48 // model. 49 *aUniqueID = MsaaAccessible::GetChildIDFor(acc); 50 if (acc->IsText()) { 51 *aNodeType = nsINode::TEXT_NODE; 52 } else if (acc->IsDoc()) { 53 *aNodeType = nsINode::DOCUMENT_NODE; 54 } else { 55 *aNodeType = nsINode::ELEMENT_NODE; 56 } 57 if (nsAtom* tag = acc->TagName()) { 58 nsAutoString nodeName; 59 tag->ToString(nodeName); 60 *aNodeName = ::SysAllocString(nodeName.get()); 61 } 62 return S_OK; 63 } 64 65 STDMETHODIMP 66 sdnAccessible::get_attributes(unsigned short aMaxAttribs, 67 BSTR __RPC_FAR* aAttribNames, 68 short __RPC_FAR* aNameSpaceIDs, 69 BSTR __RPC_FAR* aAttribValues, 70 unsigned short __RPC_FAR* aNumAttribs) { 71 return E_NOTIMPL; 72 } 73 74 STDMETHODIMP 75 sdnAccessible::get_attributesForNames(unsigned short aMaxAttribs, 76 BSTR __RPC_FAR* aAttribNames, 77 short __RPC_FAR* aNameSpaceID, 78 BSTR __RPC_FAR* aAttribValues) { 79 if (!aAttribNames || !aNameSpaceID || !aAttribValues) return E_INVALIDARG; 80 81 if (!mMsaa->Acc()) { 82 return CO_E_OBJNOTCONNECTED; 83 } 84 // NVDA expects this to succeed for MathML and won't call innerHTML if this 85 // fails. Therefore, return S_FALSE here instead of E_NOTIMPL, indicating 86 // that the attributes aren't present. 87 return S_FALSE; 88 } 89 90 STDMETHODIMP 91 sdnAccessible::get_computedStyle( 92 unsigned short aMaxStyleProperties, boolean aUseAlternateView, 93 BSTR __RPC_FAR* aStyleProperties, BSTR __RPC_FAR* aStyleValues, 94 unsigned short __RPC_FAR* aNumStyleProperties) { 95 return E_NOTIMPL; 96 } 97 98 STDMETHODIMP 99 sdnAccessible::get_computedStyleForProperties( 100 unsigned short aNumStyleProperties, boolean aUseAlternateView, 101 BSTR __RPC_FAR* aStyleProperties, BSTR __RPC_FAR* aStyleValues) { 102 return E_NOTIMPL; 103 } 104 105 // XXX Use MOZ_CAN_RUN_SCRIPT_BOUNDARY for now due to bug 1543294. 106 MOZ_CAN_RUN_SCRIPT_BOUNDARY STDMETHODIMP 107 sdnAccessible::scrollTo(boolean aScrollTopLeft) { 108 return E_NOTIMPL; 109 } 110 111 STDMETHODIMP 112 sdnAccessible::get_parentNode(ISimpleDOMNode __RPC_FAR* __RPC_FAR* aNode) { 113 return E_NOTIMPL; 114 } 115 116 STDMETHODIMP 117 sdnAccessible::get_firstChild(ISimpleDOMNode __RPC_FAR* __RPC_FAR* aNode) { 118 return E_NOTIMPL; 119 } 120 121 STDMETHODIMP 122 sdnAccessible::get_lastChild(ISimpleDOMNode __RPC_FAR* __RPC_FAR* aNode) { 123 return E_NOTIMPL; 124 } 125 126 STDMETHODIMP 127 sdnAccessible::get_previousSibling(ISimpleDOMNode __RPC_FAR* __RPC_FAR* aNode) { 128 return E_NOTIMPL; 129 } 130 131 STDMETHODIMP 132 sdnAccessible::get_nextSibling(ISimpleDOMNode __RPC_FAR* __RPC_FAR* aNode) { 133 return E_NOTIMPL; 134 } 135 136 STDMETHODIMP 137 sdnAccessible::get_childAt(unsigned aChildIndex, 138 ISimpleDOMNode __RPC_FAR* __RPC_FAR* aNode) { 139 return E_NOTIMPL; 140 } 141 142 STDMETHODIMP 143 sdnAccessible::get_innerHTML(BSTR __RPC_FAR* aInnerHTML) { 144 if (!aInnerHTML) return E_INVALIDARG; 145 *aInnerHTML = nullptr; 146 147 Accessible* acc = mMsaa->Acc(); 148 if (!acc) { 149 return CO_E_OBJNOTCONNECTED; 150 } 151 152 nsAutoString innerHTML; 153 if (RemoteAccessible* remoteAcc = acc->AsRemote()) { 154 if (RequestDomainsIfInactive(CacheDomain::InnerHTML)) { 155 return S_FALSE; 156 } 157 if (!remoteAcc->mCachedFields) { 158 return S_FALSE; 159 } 160 remoteAcc->mCachedFields->GetAttribute(CacheKey::InnerHTML, innerHTML); 161 } else { 162 if (dom::Element* el = acc->AsLocal()->Elm()) { 163 el->GetInnerHTML(innerHTML, IgnoreErrors()); 164 } 165 } 166 167 if (innerHTML.IsEmpty()) return S_FALSE; 168 169 *aInnerHTML = ::SysAllocStringLen(innerHTML.get(), innerHTML.Length()); 170 if (!*aInnerHTML) return E_OUTOFMEMORY; 171 172 return S_OK; 173 } 174 175 STDMETHODIMP 176 sdnAccessible::get_localInterface(void __RPC_FAR* __RPC_FAR* aLocalInterface) { 177 if (!aLocalInterface) return E_INVALIDARG; 178 *aLocalInterface = nullptr; 179 180 if (!mMsaa->Acc()) { 181 return CO_E_OBJNOTCONNECTED; 182 } 183 184 *aLocalInterface = this; 185 AddRef(); 186 187 return S_OK; 188 } 189 190 STDMETHODIMP 191 sdnAccessible::get_language(BSTR __RPC_FAR* aLanguage) { return E_NOTIMPL; }