diff options
Diffstat (limited to 'accessible/windows/msaa/MsaaDocAccessible.cpp')
-rw-r--r-- | accessible/windows/msaa/MsaaDocAccessible.cpp | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/accessible/windows/msaa/MsaaDocAccessible.cpp b/accessible/windows/msaa/MsaaDocAccessible.cpp new file mode 100644 index 0000000000..615f2e5d39 --- /dev/null +++ b/accessible/windows/msaa/MsaaDocAccessible.cpp @@ -0,0 +1,133 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "MsaaDocAccessible.h" + +#include "MsaaDocAccessible.h" +#include "DocAccessibleChild.h" +#include "mozilla/a11y/DocAccessibleParent.h" +#include "nsAccessibilityService.h" +#include "nsAccUtils.h" +#include "nsWinUtils.h" +#include "Statistics.h" +#include "sdnDocAccessible.h" +#include "mozilla/a11y/Role.h" +#include "ISimpleDOM.h" + +using namespace mozilla; +using namespace mozilla::a11y; + +DocAccessible* MsaaDocAccessible::DocAcc() { + return static_cast<DocAccessible*>(LocalAcc()); +} + +/* static */ +MsaaDocAccessible* MsaaDocAccessible::GetFrom(DocAccessible* aDoc) { + return static_cast<MsaaDocAccessible*>(MsaaAccessible::GetFrom(aDoc)); +} + +/* static */ +MsaaDocAccessible* MsaaDocAccessible::GetFrom(DocAccessibleParent* aDoc) { + return static_cast<MsaaDocAccessible*>( + reinterpret_cast<MsaaAccessible*>(aDoc->GetWrapper())); +} + +/* static */ +MsaaDocAccessible* MsaaDocAccessible::GetFromOwned(Accessible* aAcc) { + if (RemoteAccessible* remoteAcc = aAcc->AsRemote()) { + DocAccessibleParent* doc = remoteAcc->Document(); + if (!doc) { + return nullptr; + } + return MsaaDocAccessible::GetFrom(doc); + } + DocAccessible* doc = aAcc->AsLocal()->Document(); + if (!doc) { + return nullptr; + } + return MsaaDocAccessible::GetFrom(doc); +} + +// IUnknown +IMPL_IUNKNOWN_QUERY_HEAD(MsaaDocAccessible) +if (aIID == IID_ISimpleDOMDocument && LocalAcc()) { + statistics::ISimpleDOMUsed(); + *aInstancePtr = static_cast<ISimpleDOMDocument*>(new sdnDocAccessible(this)); + static_cast<IUnknown*>(*aInstancePtr)->AddRef(); + return S_OK; +} +IMPL_IUNKNOWN_QUERY_TAIL_INHERITED(ia2AccessibleHypertext) + +STDMETHODIMP +MsaaDocAccessible::get_accParent( + /* [retval][out] */ IDispatch __RPC_FAR* __RPC_FAR* ppdispParent) { + if (!mAcc) { + return CO_E_OBJNOTCONNECTED; + } + + if (mAcc->IsRemote()) { + DocAccessibleParent* remoteDoc = mAcc->AsRemote()->AsDoc(); + if (nsWinUtils::IsWindowEmulationStarted() && remoteDoc->IsTopLevel()) { + // Window emulation is enabled and this is a top level document. Return + // window system accessible object. + HWND hwnd = remoteDoc->GetEmulatedWindowHandle(); + MOZ_ASSERT(hwnd); + if (hwnd && + SUCCEEDED(::CreateStdAccessibleObject( + hwnd, OBJID_WINDOW, IID_IAccessible, (void**)ppdispParent))) { + return S_OK; + } + } + return MsaaAccessible::get_accParent(ppdispParent); + } + + DocAccessible* docAcc = DocAcc(); + MOZ_ASSERT(docAcc); + + // Return window system accessible object for root document accessibles, as + // well as tab document accessibles if window emulation is enabled. + MOZ_ASSERT(XRE_IsParentProcess()); + if ((!docAcc->ParentDocument() || + (nsWinUtils::IsWindowEmulationStarted() && + nsCoreUtils::IsTopLevelContentDocInProcess(docAcc->DocumentNode())))) { + HWND hwnd = static_cast<HWND>(docAcc->GetNativeWindow()); + if (hwnd && + SUCCEEDED(::CreateStdAccessibleObject( + hwnd, OBJID_WINDOW, IID_IAccessible, (void**)ppdispParent))) { + return S_OK; + } + } + + return MsaaAccessible::get_accParent(ppdispParent); +} + +STDMETHODIMP +MsaaDocAccessible::get_accValue(VARIANT aVarChild, BSTR __RPC_FAR* aValue) { + if (!aValue) return E_INVALIDARG; + *aValue = nullptr; + + // For backwards-compat, we still support old MSAA hack to provide URL in + // accValue Check for real value first + HRESULT hr = MsaaAccessible::get_accValue(aVarChild, aValue); + if (FAILED(hr) || *aValue || aVarChild.lVal != CHILDID_SELF) return hr; + + // MsaaAccessible::get_accValue should have failed (and thus we should have + // returned early) if the Accessible is dead. + MOZ_ASSERT(mAcc); + // If document is being used to create a widget, don't use the URL hack + roles::Role role = mAcc->Role(); + if (role != roles::DOCUMENT && role != roles::APPLICATION && + role != roles::DIALOG && role != roles::ALERT && + role != roles::NON_NATIVE_DOCUMENT) + return hr; + + nsAutoString url; + nsAccUtils::DocumentURL(mAcc, url); + if (url.IsEmpty()) return S_FALSE; + + *aValue = ::SysAllocStringLen(url.get(), url.Length()); + return *aValue ? S_OK : E_OUTOFMEMORY; +} |