|
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 "nsWinUtils.h" |
|
11 #include "mozilla/dom/TabChild.h" |
|
12 #include "Role.h" |
|
13 #include "RootAccessible.h" |
|
14 #include "sdnDocAccessible.h" |
|
15 #include "Statistics.h" |
|
16 |
|
17 #include "nsIDocShell.h" |
|
18 #include "nsIInterfaceRequestorUtils.h" |
|
19 |
|
20 using namespace mozilla; |
|
21 using namespace mozilla::a11y; |
|
22 |
|
23 //////////////////////////////////////////////////////////////////////////////// |
|
24 // DocAccessibleWrap |
|
25 //////////////////////////////////////////////////////////////////////////////// |
|
26 |
|
27 DocAccessibleWrap:: |
|
28 DocAccessibleWrap(nsIDocument* aDocument, nsIContent* aRootContent, |
|
29 nsIPresShell* aPresShell) : |
|
30 DocAccessible(aDocument, aRootContent, aPresShell), mHWND(nullptr) |
|
31 { |
|
32 } |
|
33 |
|
34 DocAccessibleWrap::~DocAccessibleWrap() |
|
35 { |
|
36 } |
|
37 |
|
38 IMPL_IUNKNOWN_QUERY_HEAD(DocAccessibleWrap) |
|
39 if (aIID == IID_ISimpleDOMDocument) { |
|
40 statistics::ISimpleDOMUsed(); |
|
41 *aInstancePtr = static_cast<ISimpleDOMDocument*>(new sdnDocAccessible(this)); |
|
42 static_cast<IUnknown*>(*aInstancePtr)->AddRef(); |
|
43 return S_OK; |
|
44 } |
|
45 IMPL_IUNKNOWN_QUERY_TAIL_INHERITED(HyperTextAccessibleWrap) |
|
46 |
|
47 STDMETHODIMP |
|
48 DocAccessibleWrap::get_accValue(VARIANT aVarChild, BSTR __RPC_FAR* aValue) |
|
49 { |
|
50 A11Y_TRYBLOCK_BEGIN |
|
51 |
|
52 if (!aValue) |
|
53 return E_INVALIDARG; |
|
54 *aValue = nullptr; |
|
55 |
|
56 // For backwards-compat, we still support old MSAA hack to provide URL in accValue |
|
57 // Check for real value first |
|
58 HRESULT hr = AccessibleWrap::get_accValue(aVarChild, aValue); |
|
59 if (FAILED(hr) || *aValue || aVarChild.lVal != CHILDID_SELF) |
|
60 return hr; |
|
61 |
|
62 // If document is being used to create a widget, don't use the URL hack |
|
63 roles::Role role = Role(); |
|
64 if (role != roles::DOCUMENT && role != roles::APPLICATION && |
|
65 role != roles::DIALOG && role != roles::ALERT) |
|
66 return hr; |
|
67 |
|
68 nsAutoString URL; |
|
69 nsresult rv = GetURL(URL); |
|
70 if (URL.IsEmpty()) |
|
71 return S_FALSE; |
|
72 |
|
73 *aValue = ::SysAllocStringLen(URL.get(), URL.Length()); |
|
74 return *aValue ? S_OK : E_OUTOFMEMORY; |
|
75 |
|
76 A11Y_TRYBLOCK_END |
|
77 } |
|
78 |
|
79 //////////////////////////////////////////////////////////////////////////////// |
|
80 // Accessible |
|
81 |
|
82 void |
|
83 DocAccessibleWrap::Shutdown() |
|
84 { |
|
85 // Do window emulation specific shutdown if emulation was started. |
|
86 if (nsWinUtils::IsWindowEmulationStarted()) { |
|
87 // Destroy window created for root document. |
|
88 if (mDocFlags & eTabDocument) { |
|
89 nsWinUtils::sHWNDCache->Remove(mHWND); |
|
90 ::DestroyWindow(static_cast<HWND>(mHWND)); |
|
91 } |
|
92 |
|
93 mHWND = nullptr; |
|
94 } |
|
95 |
|
96 DocAccessible::Shutdown(); |
|
97 } |
|
98 |
|
99 //////////////////////////////////////////////////////////////////////////////// |
|
100 // DocAccessible public |
|
101 |
|
102 void* |
|
103 DocAccessibleWrap::GetNativeWindow() const |
|
104 { |
|
105 return mHWND ? mHWND : DocAccessible::GetNativeWindow(); |
|
106 } |
|
107 |
|
108 //////////////////////////////////////////////////////////////////////////////// |
|
109 // DocAccessible protected |
|
110 |
|
111 void |
|
112 DocAccessibleWrap::DoInitialUpdate() |
|
113 { |
|
114 DocAccessible::DoInitialUpdate(); |
|
115 |
|
116 if (nsWinUtils::IsWindowEmulationStarted()) { |
|
117 // Create window for tab document. |
|
118 if (mDocFlags & eTabDocument) { |
|
119 mozilla::dom::TabChild* tabChild = |
|
120 mozilla::dom::TabChild::GetFrom(mDocumentNode->GetShell()); |
|
121 |
|
122 a11y::RootAccessible* rootDocument = RootAccessible(); |
|
123 |
|
124 mozilla::WindowsHandle nativeData = 0; |
|
125 if (tabChild) |
|
126 tabChild->SendGetWidgetNativeData(&nativeData); |
|
127 else |
|
128 nativeData = reinterpret_cast<mozilla::WindowsHandle>( |
|
129 rootDocument->GetNativeWindow()); |
|
130 |
|
131 bool isActive = true; |
|
132 int32_t x = CW_USEDEFAULT, y = CW_USEDEFAULT, width = 0, height = 0; |
|
133 if (Compatibility::IsDolphin()) { |
|
134 GetBounds(&x, &y, &width, &height); |
|
135 int32_t rootX = 0, rootY = 0, rootWidth = 0, rootHeight = 0; |
|
136 rootDocument->GetBounds(&rootX, &rootY, &rootWidth, &rootHeight); |
|
137 x = rootX - x; |
|
138 y -= rootY; |
|
139 |
|
140 nsCOMPtr<nsISupports> container = mDocumentNode->GetContainer(); |
|
141 nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(container); |
|
142 docShell->GetIsActive(&isActive); |
|
143 } |
|
144 |
|
145 HWND parentWnd = reinterpret_cast<HWND>(nativeData); |
|
146 mHWND = nsWinUtils::CreateNativeWindow(kClassNameTabContent, parentWnd, |
|
147 x, y, width, height, isActive); |
|
148 |
|
149 nsWinUtils::sHWNDCache->Put(mHWND, this); |
|
150 |
|
151 } else { |
|
152 DocAccessible* parentDocument = ParentDocument(); |
|
153 if (parentDocument) |
|
154 mHWND = parentDocument->GetNativeWindow(); |
|
155 } |
|
156 } |
|
157 } |