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 "DocAccessibleWrap.h"
8 
9 #include "Compatibility.h"
10 #include "mozilla/PresShell.h"
11 #include "mozilla/dom/Document.h"
12 #include "DocAccessibleChild.h"
13 #include "nsWinUtils.h"
14 #include "RootAccessible.h"
15 #include "sdnDocAccessible.h"
16 #include "Statistics.h"
17 
18 using namespace mozilla;
19 using namespace mozilla::a11y;
20 
21 ////////////////////////////////////////////////////////////////////////////////
22 // DocAccessibleWrap
23 ////////////////////////////////////////////////////////////////////////////////
24 
DocAccessibleWrap(dom::Document * aDocument,PresShell * aPresShell)25 DocAccessibleWrap::DocAccessibleWrap(dom::Document* aDocument,
26                                      PresShell* aPresShell)
27     : DocAccessible(aDocument, aPresShell), mHWND(nullptr) {}
28 
~DocAccessibleWrap()29 DocAccessibleWrap::~DocAccessibleWrap() {}
30 
31 ////////////////////////////////////////////////////////////////////////////////
32 // LocalAccessible
33 
Shutdown()34 void DocAccessibleWrap::Shutdown() {
35   // Do window emulation specific shutdown if emulation was started.
36   if (nsWinUtils::IsWindowEmulationStarted()) {
37     // Destroy window created for root document.
38     if (mDocFlags & eTopLevelContentDocInProcess) {
39       MOZ_ASSERT(XRE_IsParentProcess());
40       HWND hWnd = static_cast<HWND>(mHWND);
41       ::RemovePropW(hWnd, kPropNameDocAcc);
42       ::DestroyWindow(hWnd);
43     }
44 
45     mHWND = nullptr;
46   }
47 
48   DocAccessible::Shutdown();
49 }
50 
51 ////////////////////////////////////////////////////////////////////////////////
52 // DocAccessible public
53 
GetNativeWindow() const54 void* DocAccessibleWrap::GetNativeWindow() const {
55   if (XRE_IsContentProcess()) {
56     DocAccessibleChild* ipcDoc = IPCDoc();
57     if (!ipcDoc) {
58       return nullptr;
59     }
60 
61     return ipcDoc->GetNativeWindowHandle();
62   } else if (mHWND) {
63     return mHWND;
64   }
65   return DocAccessible::GetNativeWindow();
66 }
67 
68 ////////////////////////////////////////////////////////////////////////////////
69 // DocAccessible protected
70 
DoInitialUpdate()71 void DocAccessibleWrap::DoInitialUpdate() {
72   DocAccessible::DoInitialUpdate();
73 
74   if (nsWinUtils::IsWindowEmulationStarted()) {
75     // Create window for tab document.
76     if (mDocFlags & eTopLevelContentDocInProcess) {
77       MOZ_ASSERT(XRE_IsParentProcess());
78       a11y::RootAccessible* rootDocument = RootAccessible();
79       bool isActive = true;
80       nsIntRect rect(CW_USEDEFAULT, CW_USEDEFAULT, 0, 0);
81       if (Compatibility::IsDolphin()) {
82         rect = Bounds();
83         nsIntRect rootRect = rootDocument->Bounds();
84         rect.MoveToX(rootRect.X() - rect.X());
85         rect.MoveByY(-rootRect.Y());
86 
87         auto* bc = mDocumentNode->GetBrowsingContext();
88         isActive = bc && bc->IsActive();
89       }
90 
91       RefPtr<DocAccessibleWrap> self(this);
92       nsWinUtils::NativeWindowCreateProc onCreate([self](HWND aHwnd) -> void {
93         ::SetPropW(aHwnd, kPropNameDocAcc,
94                    reinterpret_cast<HANDLE>(self.get()));
95       });
96 
97       HWND parentWnd = reinterpret_cast<HWND>(rootDocument->GetNativeWindow());
98       mHWND = nsWinUtils::CreateNativeWindow(
99           kClassNameTabContent, parentWnd, rect.X(), rect.Y(), rect.Width(),
100           rect.Height(), isActive, &onCreate);
101     } else {
102       DocAccessible* parentDocument = ParentDocument();
103       if (parentDocument) mHWND = parentDocument->GetNativeWindow();
104     }
105   }
106 }
107