diff -r 000000000000 -r 6474c204b198 accessible/src/windows/msaa/DocAccessibleWrap.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accessible/src/windows/msaa/DocAccessibleWrap.cpp Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,157 @@ +/* -*- 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 "DocAccessibleWrap.h" + +#include "Compatibility.h" +#include "nsWinUtils.h" +#include "mozilla/dom/TabChild.h" +#include "Role.h" +#include "RootAccessible.h" +#include "sdnDocAccessible.h" +#include "Statistics.h" + +#include "nsIDocShell.h" +#include "nsIInterfaceRequestorUtils.h" + +using namespace mozilla; +using namespace mozilla::a11y; + +//////////////////////////////////////////////////////////////////////////////// +// DocAccessibleWrap +//////////////////////////////////////////////////////////////////////////////// + +DocAccessibleWrap:: + DocAccessibleWrap(nsIDocument* aDocument, nsIContent* aRootContent, + nsIPresShell* aPresShell) : + DocAccessible(aDocument, aRootContent, aPresShell), mHWND(nullptr) +{ +} + +DocAccessibleWrap::~DocAccessibleWrap() +{ +} + +IMPL_IUNKNOWN_QUERY_HEAD(DocAccessibleWrap) + if (aIID == IID_ISimpleDOMDocument) { + statistics::ISimpleDOMUsed(); + *aInstancePtr = static_cast(new sdnDocAccessible(this)); + static_cast(*aInstancePtr)->AddRef(); + return S_OK; + } +IMPL_IUNKNOWN_QUERY_TAIL_INHERITED(HyperTextAccessibleWrap) + +STDMETHODIMP +DocAccessibleWrap::get_accValue(VARIANT aVarChild, BSTR __RPC_FAR* aValue) +{ + A11Y_TRYBLOCK_BEGIN + + 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 = AccessibleWrap::get_accValue(aVarChild, aValue); + if (FAILED(hr) || *aValue || aVarChild.lVal != CHILDID_SELF) + return hr; + + // If document is being used to create a widget, don't use the URL hack + roles::Role role = Role(); + if (role != roles::DOCUMENT && role != roles::APPLICATION && + role != roles::DIALOG && role != roles::ALERT) + return hr; + + nsAutoString URL; + nsresult rv = GetURL(URL); + if (URL.IsEmpty()) + return S_FALSE; + + *aValue = ::SysAllocStringLen(URL.get(), URL.Length()); + return *aValue ? S_OK : E_OUTOFMEMORY; + + A11Y_TRYBLOCK_END +} + +//////////////////////////////////////////////////////////////////////////////// +// Accessible + +void +DocAccessibleWrap::Shutdown() +{ + // Do window emulation specific shutdown if emulation was started. + if (nsWinUtils::IsWindowEmulationStarted()) { + // Destroy window created for root document. + if (mDocFlags & eTabDocument) { + nsWinUtils::sHWNDCache->Remove(mHWND); + ::DestroyWindow(static_cast(mHWND)); + } + + mHWND = nullptr; + } + + DocAccessible::Shutdown(); +} + +//////////////////////////////////////////////////////////////////////////////// +// DocAccessible public + +void* +DocAccessibleWrap::GetNativeWindow() const +{ + return mHWND ? mHWND : DocAccessible::GetNativeWindow(); +} + +//////////////////////////////////////////////////////////////////////////////// +// DocAccessible protected + +void +DocAccessibleWrap::DoInitialUpdate() +{ + DocAccessible::DoInitialUpdate(); + + if (nsWinUtils::IsWindowEmulationStarted()) { + // Create window for tab document. + if (mDocFlags & eTabDocument) { + mozilla::dom::TabChild* tabChild = + mozilla::dom::TabChild::GetFrom(mDocumentNode->GetShell()); + + a11y::RootAccessible* rootDocument = RootAccessible(); + + mozilla::WindowsHandle nativeData = 0; + if (tabChild) + tabChild->SendGetWidgetNativeData(&nativeData); + else + nativeData = reinterpret_cast( + rootDocument->GetNativeWindow()); + + bool isActive = true; + int32_t x = CW_USEDEFAULT, y = CW_USEDEFAULT, width = 0, height = 0; + if (Compatibility::IsDolphin()) { + GetBounds(&x, &y, &width, &height); + int32_t rootX = 0, rootY = 0, rootWidth = 0, rootHeight = 0; + rootDocument->GetBounds(&rootX, &rootY, &rootWidth, &rootHeight); + x = rootX - x; + y -= rootY; + + nsCOMPtr container = mDocumentNode->GetContainer(); + nsCOMPtr docShell = do_QueryInterface(container); + docShell->GetIsActive(&isActive); + } + + HWND parentWnd = reinterpret_cast(nativeData); + mHWND = nsWinUtils::CreateNativeWindow(kClassNameTabContent, parentWnd, + x, y, width, height, isActive); + + nsWinUtils::sHWNDCache->Put(mHWND, this); + + } else { + DocAccessible* parentDocument = ParentDocument(); + if (parentDocument) + mHWND = parentDocument->GetNativeWindow(); + } + } +}