michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* vim: set ts=2 et sw=2 tw=80: */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "DocAccessibleWrap.h" michael@0: michael@0: #include "Compatibility.h" michael@0: #include "nsWinUtils.h" michael@0: #include "mozilla/dom/TabChild.h" michael@0: #include "Role.h" michael@0: #include "RootAccessible.h" michael@0: #include "sdnDocAccessible.h" michael@0: #include "Statistics.h" michael@0: michael@0: #include "nsIDocShell.h" michael@0: #include "nsIInterfaceRequestorUtils.h" michael@0: michael@0: using namespace mozilla; michael@0: using namespace mozilla::a11y; michael@0: michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: // DocAccessibleWrap michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: michael@0: DocAccessibleWrap:: michael@0: DocAccessibleWrap(nsIDocument* aDocument, nsIContent* aRootContent, michael@0: nsIPresShell* aPresShell) : michael@0: DocAccessible(aDocument, aRootContent, aPresShell), mHWND(nullptr) michael@0: { michael@0: } michael@0: michael@0: DocAccessibleWrap::~DocAccessibleWrap() michael@0: { michael@0: } michael@0: michael@0: IMPL_IUNKNOWN_QUERY_HEAD(DocAccessibleWrap) michael@0: if (aIID == IID_ISimpleDOMDocument) { michael@0: statistics::ISimpleDOMUsed(); michael@0: *aInstancePtr = static_cast(new sdnDocAccessible(this)); michael@0: static_cast(*aInstancePtr)->AddRef(); michael@0: return S_OK; michael@0: } michael@0: IMPL_IUNKNOWN_QUERY_TAIL_INHERITED(HyperTextAccessibleWrap) michael@0: michael@0: STDMETHODIMP michael@0: DocAccessibleWrap::get_accValue(VARIANT aVarChild, BSTR __RPC_FAR* aValue) michael@0: { michael@0: A11Y_TRYBLOCK_BEGIN michael@0: michael@0: if (!aValue) michael@0: return E_INVALIDARG; michael@0: *aValue = nullptr; michael@0: michael@0: // For backwards-compat, we still support old MSAA hack to provide URL in accValue michael@0: // Check for real value first michael@0: HRESULT hr = AccessibleWrap::get_accValue(aVarChild, aValue); michael@0: if (FAILED(hr) || *aValue || aVarChild.lVal != CHILDID_SELF) michael@0: return hr; michael@0: michael@0: // If document is being used to create a widget, don't use the URL hack michael@0: roles::Role role = Role(); michael@0: if (role != roles::DOCUMENT && role != roles::APPLICATION && michael@0: role != roles::DIALOG && role != roles::ALERT) michael@0: return hr; michael@0: michael@0: nsAutoString URL; michael@0: nsresult rv = GetURL(URL); michael@0: if (URL.IsEmpty()) michael@0: return S_FALSE; michael@0: michael@0: *aValue = ::SysAllocStringLen(URL.get(), URL.Length()); michael@0: return *aValue ? S_OK : E_OUTOFMEMORY; michael@0: michael@0: A11Y_TRYBLOCK_END michael@0: } michael@0: michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: // Accessible michael@0: michael@0: void michael@0: DocAccessibleWrap::Shutdown() michael@0: { michael@0: // Do window emulation specific shutdown if emulation was started. michael@0: if (nsWinUtils::IsWindowEmulationStarted()) { michael@0: // Destroy window created for root document. michael@0: if (mDocFlags & eTabDocument) { michael@0: nsWinUtils::sHWNDCache->Remove(mHWND); michael@0: ::DestroyWindow(static_cast(mHWND)); michael@0: } michael@0: michael@0: mHWND = nullptr; michael@0: } michael@0: michael@0: DocAccessible::Shutdown(); michael@0: } michael@0: michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: // DocAccessible public michael@0: michael@0: void* michael@0: DocAccessibleWrap::GetNativeWindow() const michael@0: { michael@0: return mHWND ? mHWND : DocAccessible::GetNativeWindow(); michael@0: } michael@0: michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: // DocAccessible protected michael@0: michael@0: void michael@0: DocAccessibleWrap::DoInitialUpdate() michael@0: { michael@0: DocAccessible::DoInitialUpdate(); michael@0: michael@0: if (nsWinUtils::IsWindowEmulationStarted()) { michael@0: // Create window for tab document. michael@0: if (mDocFlags & eTabDocument) { michael@0: mozilla::dom::TabChild* tabChild = michael@0: mozilla::dom::TabChild::GetFrom(mDocumentNode->GetShell()); michael@0: michael@0: a11y::RootAccessible* rootDocument = RootAccessible(); michael@0: michael@0: mozilla::WindowsHandle nativeData = 0; michael@0: if (tabChild) michael@0: tabChild->SendGetWidgetNativeData(&nativeData); michael@0: else michael@0: nativeData = reinterpret_cast( michael@0: rootDocument->GetNativeWindow()); michael@0: michael@0: bool isActive = true; michael@0: int32_t x = CW_USEDEFAULT, y = CW_USEDEFAULT, width = 0, height = 0; michael@0: if (Compatibility::IsDolphin()) { michael@0: GetBounds(&x, &y, &width, &height); michael@0: int32_t rootX = 0, rootY = 0, rootWidth = 0, rootHeight = 0; michael@0: rootDocument->GetBounds(&rootX, &rootY, &rootWidth, &rootHeight); michael@0: x = rootX - x; michael@0: y -= rootY; michael@0: michael@0: nsCOMPtr container = mDocumentNode->GetContainer(); michael@0: nsCOMPtr docShell = do_QueryInterface(container); michael@0: docShell->GetIsActive(&isActive); michael@0: } michael@0: michael@0: HWND parentWnd = reinterpret_cast(nativeData); michael@0: mHWND = nsWinUtils::CreateNativeWindow(kClassNameTabContent, parentWnd, michael@0: x, y, width, height, isActive); michael@0: michael@0: nsWinUtils::sHWNDCache->Put(mHWND, this); michael@0: michael@0: } else { michael@0: DocAccessible* parentDocument = ParentDocument(); michael@0: if (parentDocument) michael@0: mHWND = parentDocument->GetNativeWindow(); michael@0: } michael@0: } michael@0: }