Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "OuterDocAccessible.h"
8 #include "Accessible-inl.h"
9 #include "nsAccUtils.h"
10 #include "DocAccessible-inl.h"
11 #include "Role.h"
12 #include "States.h"
14 #ifdef A11Y_LOG
15 #include "Logging.h"
16 #endif
18 using namespace mozilla;
19 using namespace mozilla::a11y;
21 ////////////////////////////////////////////////////////////////////////////////
22 // OuterDocAccessible
23 ////////////////////////////////////////////////////////////////////////////////
25 OuterDocAccessible::
26 OuterDocAccessible(nsIContent* aContent, DocAccessible* aDoc) :
27 AccessibleWrap(aContent, aDoc)
28 {
29 }
31 OuterDocAccessible::~OuterDocAccessible()
32 {
33 }
35 ////////////////////////////////////////////////////////////////////////////////
36 // nsISupports
38 NS_IMPL_ISUPPORTS_INHERITED0(OuterDocAccessible,
39 Accessible)
41 ////////////////////////////////////////////////////////////////////////////////
42 // Accessible public (DON'T add methods here)
44 role
45 OuterDocAccessible::NativeRole()
46 {
47 return roles::INTERNAL_FRAME;
48 }
50 Accessible*
51 OuterDocAccessible::ChildAtPoint(int32_t aX, int32_t aY,
52 EWhichChildAtPoint aWhichChild)
53 {
54 int32_t docX = 0, docY = 0, docWidth = 0, docHeight = 0;
55 nsresult rv = GetBounds(&docX, &docY, &docWidth, &docHeight);
56 NS_ENSURE_SUCCESS(rv, nullptr);
58 if (aX < docX || aX >= docX + docWidth || aY < docY || aY >= docY + docHeight)
59 return nullptr;
61 // Always return the inner doc as direct child accessible unless bounds
62 // outside of it.
63 Accessible* child = GetChildAt(0);
64 NS_ENSURE_TRUE(child, nullptr);
66 if (aWhichChild == eDeepestChild)
67 return child->ChildAtPoint(aX, aY, eDeepestChild);
68 return child;
69 }
71 ////////////////////////////////////////////////////////////////////////////////
72 // nsIAccessible
74 uint8_t
75 OuterDocAccessible::ActionCount()
76 {
77 // Internal frame, which is the doc's parent, should not have a click action.
78 return 0;
79 }
81 NS_IMETHODIMP
82 OuterDocAccessible::GetActionName(uint8_t aIndex, nsAString& aName)
83 {
84 aName.Truncate();
86 return NS_ERROR_INVALID_ARG;
87 }
89 NS_IMETHODIMP
90 OuterDocAccessible::GetActionDescription(uint8_t aIndex,
91 nsAString& aDescription)
92 {
93 aDescription.Truncate();
95 return NS_ERROR_INVALID_ARG;
96 }
98 NS_IMETHODIMP
99 OuterDocAccessible::DoAction(uint8_t aIndex)
100 {
101 return NS_ERROR_INVALID_ARG;
102 }
104 ////////////////////////////////////////////////////////////////////////////////
105 // Accessible public
107 void
108 OuterDocAccessible::Shutdown()
109 {
110 // XXX: sometimes outerdoc accessible is shutdown because of layout style
111 // change however the presshell of underlying document isn't destroyed and
112 // the document doesn't get pagehide events. Schedule a document rebind
113 // to its parent document. Otherwise a document accessible may be lost if its
114 // outerdoc has being recreated (see bug 862863 for details).
116 #ifdef A11Y_LOG
117 if (logging::IsEnabled(logging::eDocDestroy))
118 logging::OuterDocDestroy(this);
119 #endif
121 Accessible* child = mChildren.SafeElementAt(0, nullptr);
122 if (child) {
123 #ifdef A11Y_LOG
124 if (logging::IsEnabled(logging::eDocDestroy)) {
125 logging::DocDestroy("outerdoc's child document rebind is scheduled",
126 child->AsDoc()->DocumentNode());
127 }
128 #endif
129 RemoveChild(child);
130 mDoc->BindChildDocument(child->AsDoc());
131 }
133 AccessibleWrap::Shutdown();
134 }
136 void
137 OuterDocAccessible::InvalidateChildren()
138 {
139 // Do not invalidate children because DocManager is responsible for
140 // document accessible lifetime when DOM document is created or destroyed. If
141 // DOM document isn't destroyed but its presshell is destroyed (for example,
142 // when DOM node of outerdoc accessible is hidden), then outerdoc accessible
143 // notifies DocManager about this. If presshell is created for existing
144 // DOM document (for example when DOM node of outerdoc accessible is shown)
145 // then allow DocManager to handle this case since the document
146 // accessible is created and appended as a child when it's requested.
148 SetChildrenFlag(eChildrenUninitialized);
149 }
151 bool
152 OuterDocAccessible::InsertChildAt(uint32_t aIdx, Accessible* aAccessible)
153 {
154 NS_ASSERTION(aAccessible->IsDoc(),
155 "OuterDocAccessible should only have document child!");
156 // We keep showing the old document for a bit after creating the new one,
157 // and while building the new DOM and frame tree. That's done on purpose
158 // to avoid weird flashes of default background color.
159 // The old viewer will be destroyed after the new one is created.
160 // For a11y, it should be safe to shut down the old document now.
161 if (mChildren.Length())
162 mChildren[0]->Shutdown();
164 if (!AccessibleWrap::InsertChildAt(0, aAccessible))
165 return false;
167 #ifdef A11Y_LOG
168 if (logging::IsEnabled(logging::eDocCreate)) {
169 logging::DocCreate("append document to outerdoc",
170 aAccessible->AsDoc()->DocumentNode());
171 logging::Address("outerdoc", this);
172 }
173 #endif
175 return true;
176 }
178 bool
179 OuterDocAccessible::RemoveChild(Accessible* aAccessible)
180 {
181 Accessible* child = mChildren.SafeElementAt(0, nullptr);
182 if (child != aAccessible) {
183 NS_ERROR("Wrong child to remove!");
184 return false;
185 }
187 #ifdef A11Y_LOG
188 if (logging::IsEnabled(logging::eDocDestroy)) {
189 logging::DocDestroy("remove document from outerdoc",
190 child->AsDoc()->DocumentNode(), child->AsDoc());
191 logging::Address("outerdoc", this);
192 }
193 #endif
195 bool wasRemoved = AccessibleWrap::RemoveChild(child);
197 NS_ASSERTION(!mChildren.Length(),
198 "This child document of outerdoc accessible wasn't removed!");
200 return wasRemoved;
201 }
204 ////////////////////////////////////////////////////////////////////////////////
205 // Accessible protected
207 void
208 OuterDocAccessible::CacheChildren()
209 {
210 // Request document accessible for the content document to make sure it's
211 // created. It will appended to outerdoc accessible children asynchronously.
212 nsIDocument* outerDoc = mContent->GetCurrentDoc();
213 if (outerDoc) {
214 nsIDocument* innerDoc = outerDoc->GetSubDocumentFor(mContent);
215 if (innerDoc)
216 GetAccService()->GetDocAccessible(innerDoc);
217 }
218 }