1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is mozilla.org code.
16 : *
17 : * The Initial Developer of the Original Code is
18 : * Netscape Communications Corporation.
19 : * Portions created by the Initial Developer are Copyright (C) 2003
20 : * the Initial Developer. All Rights Reserved.
21 : *
22 : * Contributor(s):
23 : * Original Author: Aaron Leventhal (aaronl@netscape.com)
24 : *
25 : * Alternatively, the contents of this file may be used under the terms of
26 : * either of the GNU General Public License Version 2 or later (the "GPL"),
27 : * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 : * in which case the provisions of the GPL or the LGPL are applicable instead
29 : * of those above. If you wish to allow use of your version of this file only
30 : * under the terms of either the GPL or the LGPL, and not to allow others to
31 : * use your version of this file under the terms of the MPL, indicate your
32 : * decision by deleting the provisions above and replace them with the notice
33 : * and other provisions required by the GPL or the LGPL. If you do not delete
34 : * the provisions above, a recipient may use your version of this file under
35 : * the terms of any one of the MPL, the GPL or the LGPL.
36 : *
37 : * ***** END LICENSE BLOCK ***** */
38 :
39 : #include "nsOuterDocAccessible.h"
40 :
41 : #include "nsAccUtils.h"
42 : #include "nsDocAccessible.h"
43 : #include "Role.h"
44 : #include "States.h"
45 :
46 : using namespace mozilla::a11y;
47 :
48 : ////////////////////////////////////////////////////////////////////////////////
49 : // nsOuterDocAccessible
50 : ////////////////////////////////////////////////////////////////////////////////
51 :
52 0 : nsOuterDocAccessible::
53 : nsOuterDocAccessible(nsIContent* aContent, nsDocAccessible* aDoc) :
54 0 : nsAccessibleWrap(aContent, aDoc)
55 : {
56 0 : }
57 :
58 : ////////////////////////////////////////////////////////////////////////////////
59 : // nsISupports
60 :
61 0 : NS_IMPL_ISUPPORTS_INHERITED0(nsOuterDocAccessible,
62 : nsAccessible)
63 :
64 : ////////////////////////////////////////////////////////////////////////////////
65 : // nsAccessible public (DON'T add methods here)
66 :
67 : role
68 0 : nsOuterDocAccessible::NativeRole()
69 : {
70 0 : return roles::INTERNAL_FRAME;
71 : }
72 :
73 : nsAccessible*
74 0 : nsOuterDocAccessible::ChildAtPoint(PRInt32 aX, PRInt32 aY,
75 : EWhichChildAtPoint aWhichChild)
76 : {
77 0 : PRInt32 docX = 0, docY = 0, docWidth = 0, docHeight = 0;
78 0 : nsresult rv = GetBounds(&docX, &docY, &docWidth, &docHeight);
79 0 : NS_ENSURE_SUCCESS(rv, nsnull);
80 :
81 0 : if (aX < docX || aX >= docX + docWidth || aY < docY || aY >= docY + docHeight)
82 0 : return nsnull;
83 :
84 : // Always return the inner doc as direct child accessible unless bounds
85 : // outside of it.
86 0 : nsAccessible* child = GetChildAt(0);
87 0 : NS_ENSURE_TRUE(child, nsnull);
88 :
89 0 : if (aWhichChild == eDeepestChild)
90 0 : return child->ChildAtPoint(aX, aY, eDeepestChild);
91 0 : return child;
92 : }
93 :
94 : nsresult
95 0 : nsOuterDocAccessible::GetAttributesInternal(nsIPersistentProperties *aAttributes)
96 : {
97 0 : nsAutoString tag;
98 0 : aAttributes->GetStringProperty(NS_LITERAL_CSTRING("tag"), tag);
99 0 : if (!tag.IsEmpty()) {
100 : // We're overriding the ARIA attributes on an sub document, but we don't want to
101 : // override the other attributes
102 0 : return NS_OK;
103 : }
104 0 : return nsAccessible::GetAttributesInternal(aAttributes);
105 : }
106 :
107 : ////////////////////////////////////////////////////////////////////////////////
108 : // nsIAccessible
109 :
110 : PRUint8
111 0 : nsOuterDocAccessible::ActionCount()
112 : {
113 : // Internal frame, which is the doc's parent, should not have a click action.
114 0 : return 0;
115 : }
116 :
117 : NS_IMETHODIMP
118 0 : nsOuterDocAccessible::GetActionName(PRUint8 aIndex, nsAString& aName)
119 : {
120 0 : aName.Truncate();
121 :
122 0 : return NS_ERROR_INVALID_ARG;
123 : }
124 :
125 : NS_IMETHODIMP
126 0 : nsOuterDocAccessible::GetActionDescription(PRUint8 aIndex, nsAString& aDescription)
127 : {
128 0 : aDescription.Truncate();
129 :
130 0 : return NS_ERROR_INVALID_ARG;
131 : }
132 :
133 : NS_IMETHODIMP
134 0 : nsOuterDocAccessible::DoAction(PRUint8 aIndex)
135 : {
136 0 : return NS_ERROR_INVALID_ARG;
137 : }
138 :
139 : ////////////////////////////////////////////////////////////////////////////////
140 : // nsAccessNode public
141 :
142 : void
143 0 : nsOuterDocAccessible::Shutdown()
144 : {
145 : // XXX: sometimes outerdoc accessible is shutdown because of layout style
146 : // change however the presshell of underlying document isn't destroyed and
147 : // the document doesn't get pagehide events. Shutdown underlying document if
148 : // any to avoid hanging document accessible.
149 : NS_LOG_ACCDOCDESTROY_MSG("A11y outerdoc shutdown")
150 : NS_LOG_ACCDOCDESTROY_ACCADDRESS("outerdoc", this)
151 :
152 0 : nsAccessible *childAcc = mChildren.SafeElementAt(0, nsnull);
153 0 : if (childAcc) {
154 : NS_LOG_ACCDOCDESTROY("outerdoc's child document shutdown",
155 : childAcc->GetDocumentNode())
156 0 : childAcc->Shutdown();
157 : }
158 :
159 0 : nsAccessibleWrap::Shutdown();
160 0 : }
161 :
162 : ////////////////////////////////////////////////////////////////////////////////
163 : // nsAccessible public
164 :
165 : void
166 0 : nsOuterDocAccessible::InvalidateChildren()
167 : {
168 : // Do not invalidate children because nsAccDocManager is responsible for
169 : // document accessible lifetime when DOM document is created or destroyed. If
170 : // DOM document isn't destroyed but its presshell is destroyed (for example,
171 : // when DOM node of outerdoc accessible is hidden), then outerdoc accessible
172 : // notifies nsAccDocManager about this. If presshell is created for existing
173 : // DOM document (for example when DOM node of outerdoc accessible is shown)
174 : // then allow nsAccDocManager to handle this case since the document
175 : // accessible is created and appended as a child when it's requested.
176 :
177 0 : SetChildrenFlag(eChildrenUninitialized);
178 0 : }
179 :
180 : bool
181 0 : nsOuterDocAccessible::AppendChild(nsAccessible *aAccessible)
182 : {
183 : // We keep showing the old document for a bit after creating the new one,
184 : // and while building the new DOM and frame tree. That's done on purpose
185 : // to avoid weird flashes of default background color.
186 : // The old viewer will be destroyed after the new one is created.
187 : // For a11y, it should be safe to shut down the old document now.
188 0 : if (mChildren.Length())
189 0 : mChildren[0]->Shutdown();
190 :
191 0 : if (!nsAccessibleWrap::AppendChild(aAccessible))
192 0 : return false;
193 :
194 : NS_LOG_ACCDOCCREATE("append document to outerdoc",
195 : aAccessible->GetDocumentNode())
196 : NS_LOG_ACCDOCCREATE_ACCADDRESS("outerdoc", this)
197 :
198 0 : return true;
199 : }
200 :
201 : bool
202 0 : nsOuterDocAccessible::RemoveChild(nsAccessible *aAccessible)
203 : {
204 0 : nsAccessible *child = mChildren.SafeElementAt(0, nsnull);
205 0 : if (child != aAccessible) {
206 0 : NS_ERROR("Wrong child to remove!");
207 0 : return false;
208 : }
209 :
210 : NS_LOG_ACCDOCDESTROY_FOR("remove document from outerdoc",
211 : child->GetDocumentNode(), child)
212 : NS_LOG_ACCDOCDESTROY_ACCADDRESS("outerdoc", this)
213 :
214 0 : bool wasRemoved = nsAccessibleWrap::RemoveChild(child);
215 :
216 0 : NS_ASSERTION(!mChildren.Length(),
217 : "This child document of outerdoc accessible wasn't removed!");
218 :
219 0 : return wasRemoved;
220 : }
221 :
222 :
223 : ////////////////////////////////////////////////////////////////////////////////
224 : // nsAccessible protected
225 :
226 : void
227 0 : nsOuterDocAccessible::CacheChildren()
228 : {
229 : // Request document accessible for the content document to make sure it's
230 : // created. It will appended to outerdoc accessible children asynchronously.
231 0 : nsIDocument* outerDoc = mContent->GetCurrentDoc();
232 0 : if (outerDoc) {
233 0 : nsIDocument* innerDoc = outerDoc->GetSubDocumentFor(mContent);
234 0 : if (innerDoc)
235 0 : GetAccService()->GetDocAccessible(innerDoc);
236 : }
237 0 : }
|