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