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
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/
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
15 * The Original Code is mozilla.org code.
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998
20 * the Initial Developer. All Rights Reserved.
23 * John Gaunt (jgaunt@netscape.com)
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.
37 * ***** END LICENSE BLOCK ***** */
39 // NOTE: alphabetically ordered
40 #include "nsAccessibilityAtoms.h"
41 #include "nsAccessibilityService.h"
42 #include "nsCoreUtils.h"
43 #include "nsAccUtils.h"
44 #include "nsARIAMap.h"
45 #include "nsIContentViewer.h"
46 #include "nsCURILoader.h"
47 #include "nsDocAccessible.h"
48 #include "nsHTMLImageAccessibleWrap.h"
49 #include "nsHTMLLinkAccessible.h"
50 #include "nsHTMLSelectAccessible.h"
51 #include "nsHTMLTableAccessibleWrap.h"
52 #include "nsHTMLTextAccessible.h"
53 #include "nsHyperTextAccessibleWrap.h"
54 #include "nsIAccessibilityService.h"
55 #include "nsIAccessibleProvider.h"
56 #include "nsIDOMDocument.h"
57 #include "nsIDOMHTMLAreaElement.h"
58 #include "nsIDOMHTMLLegendElement.h"
59 #include "nsIDOMHTMLObjectElement.h"
60 #include "nsIDOMHTMLOptGroupElement.h"
61 #include "nsIDOMHTMLOptionElement.h"
62 #include "nsIDOMWindow.h"
63 #include "nsIDOMXULElement.h"
64 #include "nsIDocShell.h"
66 #include "nsIInterfaceRequestorUtils.h"
67 #include "nsIImageFrame.h"
69 #include "nsINameSpaceManager.h"
70 #include "nsIObserverService.h"
71 #include "nsIPluginInstance.h"
72 #include "nsIPresShell.h"
73 #include "nsISupportsUtils.h"
74 #include "nsIWebNavigation.h"
75 #include "nsObjectFrame.h"
76 #include "nsOuterDocAccessible.h"
77 #include "nsRootAccessibleWrap.h"
78 #include "nsTextFragment.h"
79 #include "nsPresContext.h"
80 #include "nsServiceManagerUtils.h"
81 #include "nsUnicharUtils.h"
82 #include "nsIWebProgress.h"
83 #include "nsNetError.h"
84 #include "nsDocShellLoadTypes.h"
87 #include "nsXULAlertAccessible.h"
88 #include "nsXULColorPickerAccessible.h"
89 #include "nsXULFormControlAccessible.h"
90 #include "nsXULMenuAccessibleWrap.h"
91 #include "nsXULSelectAccessible.h"
92 #include "nsXULSliderAccessible.h"
93 #include "nsXULTabAccessible.h"
94 #include "nsXULTextAccessible.h"
95 #include "nsXULTreeAccessibleWrap.h"
98 // For native window support for object/embed/applet tags
100 #include "nsHTMLWin32ObjectAccessible.h"
103 #ifndef DISABLE_XFORMS_HOOKS
104 #include "nsXFormsFormControlsAccessible.h"
105 #include "nsXFormsWidgetsAccessible.h"
108 #ifdef MOZ_ACCESSIBILITY_ATK
109 #include "nsAppRootAccessible.h"
111 #include "nsApplicationAccessibleWrap.h"
114 nsAccessibilityService
*nsAccessibilityService::gAccessibilityService
= nsnull
;
117 * nsAccessibilityService
120 nsAccessibilityService::nsAccessibilityService()
122 nsCOMPtr
<nsIObserverService
> observerService
=
123 do_GetService("@mozilla.org/observer-service;1");
124 if (!observerService
)
127 observerService
->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID
, PR_FALSE
);
128 nsCOMPtr
<nsIWebProgress
> progress(do_GetService(NS_DOCUMENTLOADER_SERVICE_CONTRACTID
));
130 progress
->AddProgressListener(static_cast<nsIWebProgressListener
*>(this),
131 nsIWebProgress::NOTIFY_STATE_DOCUMENT
|
132 nsIWebProgress::NOTIFY_LOCATION
);
134 nsAccessNodeWrap::InitAccessibility();
137 nsAccessibilityService::~nsAccessibilityService()
139 nsAccessibilityService::gAccessibilityService
= nsnull
;
140 nsAccessNodeWrap::ShutdownAccessibility();
143 NS_IMPL_THREADSAFE_ISUPPORTS5(nsAccessibilityService
, nsIAccessibilityService
, nsIAccessibleRetrieval
,
144 nsIObserver
, nsIWebProgressListener
, nsISupportsWeakReference
)
149 nsAccessibilityService::Observe(nsISupports
*aSubject
, const char *aTopic
,
150 const PRUnichar
*aData
)
152 if (!nsCRT::strcmp(aTopic
, NS_XPCOM_SHUTDOWN_OBSERVER_ID
)) {
153 nsCOMPtr
<nsIObserverService
> observerService
=
154 do_GetService("@mozilla.org/observer-service;1");
155 if (observerService
) {
156 observerService
->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID
);
158 nsCOMPtr
<nsIWebProgress
> progress(do_GetService(NS_DOCUMENTLOADER_SERVICE_CONTRACTID
));
160 progress
->RemoveProgressListener(static_cast<nsIWebProgressListener
*>(this));
161 nsAccessNodeWrap::ShutdownAccessibility();
162 // Cancel and release load timers
163 while (mLoadTimers
.Count() > 0 ) {
164 nsCOMPtr
<nsITimer
> timer
= mLoadTimers
.ObjectAt(0);
165 void *closure
= nsnull
;
166 timer
->GetClosure(&closure
);
168 nsIWebProgress
*webProgress
= static_cast<nsIWebProgress
*>(closure
);
169 NS_RELEASE(webProgress
); // Release nsIWebProgress for timer
172 mLoadTimers
.RemoveObjectAt(0);
178 // nsIWebProgressListener
179 NS_IMETHODIMP
nsAccessibilityService::OnStateChange(nsIWebProgress
*aWebProgress
,
180 nsIRequest
*aRequest
, PRUint32 aStateFlags
, nsresult aStatus
)
182 NS_ASSERTION(aStateFlags
& STATE_IS_DOCUMENT
, "Other notifications excluded");
184 if (!aWebProgress
|| 0 == (aStateFlags
& (STATE_START
| STATE_STOP
))) {
189 aRequest
->GetName(name
);
190 if (name
.EqualsLiteral("about:blank"))
193 if (NS_FAILED(aStatus
) && (aStateFlags
& STATE_START
))
196 nsCOMPtr
<nsITimer
> timer
= do_CreateInstance("@mozilla.org/timer;1");
199 mLoadTimers
.AppendObject(timer
);
200 NS_ADDREF(aWebProgress
);
202 if (aStateFlags
& STATE_START
)
203 timer
->InitWithFuncCallback(StartLoadCallback
, aWebProgress
, 0,
204 nsITimer::TYPE_ONE_SHOT
);
205 else if (NS_SUCCEEDED(aStatus
))
206 timer
->InitWithFuncCallback(EndLoadCallback
, aWebProgress
, 0,
207 nsITimer::TYPE_ONE_SHOT
);
208 else // Failed end load
209 timer
->InitWithFuncCallback(FailedLoadCallback
, aWebProgress
, 0,
210 nsITimer::TYPE_ONE_SHOT
);
214 NS_IMETHODIMP
nsAccessibilityService::ProcessDocLoadEvent(nsITimer
*aTimer
, void *aClosure
, PRUint32 aEventType
)
216 nsCOMPtr
<nsIDOMWindow
> domWindow
;
217 nsIWebProgress
*webProgress
= static_cast<nsIWebProgress
*>(aClosure
);
218 webProgress
->GetDOMWindow(getter_AddRefs(domWindow
));
219 NS_RELEASE(webProgress
);
220 mLoadTimers
.RemoveObject(aTimer
);
221 NS_ENSURE_STATE(domWindow
);
223 if (aEventType
== nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_START
) {
224 nsCOMPtr
<nsIWebNavigation
> webNav(do_GetInterface(domWindow
));
225 nsCOMPtr
<nsIDocShell
> docShell(do_QueryInterface(webNav
));
226 NS_ENSURE_STATE(docShell
);
228 docShell
->GetLoadType(&loadType
);
229 if (loadType
== LOAD_RELOAD_NORMAL
||
230 loadType
== LOAD_RELOAD_BYPASS_CACHE
||
231 loadType
== LOAD_RELOAD_BYPASS_PROXY
||
232 loadType
== LOAD_RELOAD_BYPASS_PROXY_AND_CACHE
) {
233 aEventType
= nsIAccessibleEvent::EVENT_DOCUMENT_RELOAD
;
237 nsCOMPtr
<nsIDOMDocument
> domDoc
;
238 domWindow
->GetDocument(getter_AddRefs(domDoc
));
239 nsCOMPtr
<nsIDOMNode
> docNode
= do_QueryInterface(domDoc
);
240 NS_ENSURE_STATE(docNode
);
242 nsCOMPtr
<nsIAccessible
> accessible
;
243 GetAccessibleFor(docNode
, getter_AddRefs(accessible
));
244 nsCOMPtr
<nsPIAccessibleDocument
> privDocAccessible
= do_QueryInterface(accessible
);
245 NS_ENSURE_STATE(privDocAccessible
);
246 privDocAccessible
->FireDocLoadEvents(aEventType
);
252 nsAccessibilityService::FireAccessibleEvent(PRUint32 aEvent
,
253 nsIAccessible
*aTarget
)
255 return nsAccUtils::FireAccEvent(aEvent
, aTarget
);
258 void nsAccessibilityService::StartLoadCallback(nsITimer
*aTimer
, void *aClosure
)
260 nsIAccessibilityService
*accService
= nsAccessNode::GetAccService();
262 accService
->ProcessDocLoadEvent(aTimer
, aClosure
, nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_START
);
265 void nsAccessibilityService::EndLoadCallback(nsITimer
*aTimer
, void *aClosure
)
267 nsIAccessibilityService
*accService
= nsAccessNode::GetAccService();
269 accService
->ProcessDocLoadEvent(aTimer
, aClosure
, nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE
);
272 void nsAccessibilityService::FailedLoadCallback(nsITimer
*aTimer
, void *aClosure
)
274 nsIAccessibilityService
*accService
= nsAccessNode::GetAccService();
276 accService
->ProcessDocLoadEvent(aTimer
, aClosure
, nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_STOPPED
);
279 /* void onProgressChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long aCurSelfProgress, in long aMaxSelfProgress, in long aCurTotalProgress, in long aMaxTotalProgress); */
280 NS_IMETHODIMP
nsAccessibilityService::OnProgressChange(nsIWebProgress
*aWebProgress
,
281 nsIRequest
*aRequest
, PRInt32 aCurSelfProgress
, PRInt32 aMaxSelfProgress
,
282 PRInt32 aCurTotalProgress
, PRInt32 aMaxTotalProgress
)
284 NS_NOTREACHED("notification excluded in AddProgressListener(...)");
288 /* void onLocationChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsIURI location); */
289 NS_IMETHODIMP
nsAccessibilityService::OnLocationChange(nsIWebProgress
*aWebProgress
,
290 nsIRequest
*aRequest
, nsIURI
*location
)
292 // If the document is already loaded, this will just check to see
293 // if an anchor jump event needs to be fired.
294 // If there is no accessible for the document, we will ignore
295 // this and the anchor jump event will be fired via OnStateChange
296 // and nsIAccessibleStates::STATE_STOP
297 nsCOMPtr
<nsIDOMWindow
> domWindow
;
298 aWebProgress
->GetDOMWindow(getter_AddRefs(domWindow
));
299 NS_ASSERTION(domWindow
, "DOM Window for state change is null");
300 NS_ENSURE_TRUE(domWindow
, NS_ERROR_FAILURE
);
302 nsCOMPtr
<nsIDOMDocument
> domDoc
;
303 domWindow
->GetDocument(getter_AddRefs(domDoc
));
304 nsCOMPtr
<nsIDOMNode
> domDocRootNode(do_QueryInterface(domDoc
));
305 NS_ENSURE_TRUE(domDocRootNode
, NS_ERROR_FAILURE
);
307 nsCOMPtr
<nsIAccessibleDocument
> accessibleDoc
=
308 nsAccessNode::GetDocAccessibleFor(domDocRootNode
);
309 nsCOMPtr
<nsPIAccessibleDocument
> privateAccessibleDoc
=
310 do_QueryInterface(accessibleDoc
);
311 if (!privateAccessibleDoc
) {
314 return privateAccessibleDoc
->FireAnchorJumpEvent();
317 /* void onStatusChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsresult aStatus, in wstring aMessage); */
318 NS_IMETHODIMP
nsAccessibilityService::OnStatusChange(nsIWebProgress
*aWebProgress
,
319 nsIRequest
*aRequest
, nsresult aStatus
, const PRUnichar
*aMessage
)
321 NS_NOTREACHED("notification excluded in AddProgressListener(...)");
325 /* void onSecurityChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in unsigned long state); */
326 NS_IMETHODIMP
nsAccessibilityService::OnSecurityChange(nsIWebProgress
*aWebProgress
,
327 nsIRequest
*aRequest
, PRUint32 state
)
329 NS_NOTREACHED("notification excluded in AddProgressListener(...)");
335 nsAccessibilityService::GetInfo(nsISupports
* aFrame
, nsIFrame
** aRealFrame
, nsIWeakReference
** aShell
, nsIDOMNode
** aNode
)
337 NS_ASSERTION(aFrame
,"Error -- 1st argument (aFrame) is null!!");
338 *aRealFrame
= static_cast<nsIFrame
*>(aFrame
);
339 nsCOMPtr
<nsIContent
> content
= (*aRealFrame
)->GetContent();
340 nsCOMPtr
<nsIDOMNode
> node(do_QueryInterface(content
));
341 if (!content
|| !node
)
342 return NS_ERROR_FAILURE
;
344 NS_IF_ADDREF(*aNode
);
346 nsCOMPtr
<nsIDocument
> document
= content
->GetDocument();
348 return NS_ERROR_FAILURE
;
350 NS_ASSERTION(document
->GetPrimaryShell(),"Error no shells!");
352 // do_GetWR only works into a |nsCOMPtr| :-(
353 nsCOMPtr
<nsIWeakReference
> weakShell
=
354 do_GetWeakReference(document
->GetPrimaryShell());
355 NS_IF_ADDREF(*aShell
= weakShell
);
361 nsAccessibilityService::GetShellFromNode(nsIDOMNode
*aNode
, nsIWeakReference
**aWeakShell
)
363 nsCOMPtr
<nsIDOMDocument
> domDoc
;
364 aNode
->GetOwnerDocument(getter_AddRefs(domDoc
));
365 nsCOMPtr
<nsIDocument
> doc(do_QueryInterface(domDoc
));
367 return NS_ERROR_INVALID_ARG
;
369 // ---- Get the pres shell ----
370 nsIPresShell
*shell
= doc
->GetPrimaryShell();
372 return NS_ERROR_FAILURE
;
374 nsCOMPtr
<nsIWeakReference
> weakRef(do_GetWeakReference(shell
));
376 *aWeakShell
= weakRef
;
377 NS_IF_ADDREF(*aWeakShell
);
383 * nsIAccessibilityService methods:
387 nsAccessibilityService::CreateOuterDocAccessible(nsIDOMNode
* aDOMNode
,
388 nsIAccessible
**aOuterDocAccessible
)
390 NS_ENSURE_ARG_POINTER(aDOMNode
);
392 *aOuterDocAccessible
= nsnull
;
394 nsCOMPtr
<nsIWeakReference
> outerWeakShell
;
395 GetShellFromNode(aDOMNode
, getter_AddRefs(outerWeakShell
));
396 NS_ENSURE_TRUE(outerWeakShell
, NS_ERROR_FAILURE
);
398 nsOuterDocAccessible
*outerDocAccessible
=
399 new nsOuterDocAccessible(aDOMNode
, outerWeakShell
);
400 NS_ENSURE_TRUE(outerDocAccessible
, NS_ERROR_FAILURE
);
402 NS_ADDREF(*aOuterDocAccessible
= outerDocAccessible
);
408 nsAccessibilityService::CreateRootAccessible(nsIPresShell
*aShell
,
409 nsIDocument
* aDocument
,
410 nsIAccessible
**aRootAcc
)
414 nsCOMPtr
<nsIDOMNode
> rootNode(do_QueryInterface(aDocument
));
415 NS_ENSURE_TRUE(rootNode
, NS_ERROR_FAILURE
);
417 nsIPresShell
*presShell
= aShell
;
419 presShell
= aDocument
->GetPrimaryShell();
421 nsCOMPtr
<nsIWeakReference
> weakShell(do_GetWeakReference(presShell
));
423 nsCOMPtr
<nsISupports
> container
= aDocument
->GetContainer();
424 nsCOMPtr
<nsIDocShell
> docShell
= do_QueryInterface(container
);
425 NS_ENSURE_TRUE(docShell
, NS_ERROR_FAILURE
);
426 nsCOMPtr
<nsIContentViewer
> contentViewer
;
427 docShell
->GetContentViewer(getter_AddRefs(contentViewer
));
428 NS_ENSURE_TRUE(contentViewer
, NS_ERROR_FAILURE
); // Doc was already shut down
430 docShell
->GetBusyFlags(&busyFlags
);
431 if (busyFlags
!= nsIDocShell::BUSY_FLAGS_NONE
) {
432 nsCOMPtr
<nsIWebNavigation
> webNav(do_GetInterface(docShell
));
433 nsCOMPtr
<nsIURI
> uri
;
434 webNav
->GetCurrentURI(getter_AddRefs(uri
));
435 NS_ENSURE_STATE(uri
);
438 if (url
.EqualsLiteral("about:blank")) {
439 return NS_OK
; // No load events for a busy about:blank -- they are often temporary
443 nsCOMPtr
<nsIDocShellTreeItem
> docShellTreeItem
=
444 do_QueryInterface(container
);
445 NS_ENSURE_TRUE(docShellTreeItem
, NS_ERROR_FAILURE
);
447 nsCOMPtr
<nsIDocShellTreeItem
> parentTreeItem
;
448 docShellTreeItem
->GetParent(getter_AddRefs(parentTreeItem
));
450 if (parentTreeItem
) {
451 // We only create root accessibles for the true root, othewise create a
453 *aRootAcc
= new nsDocAccessibleWrap(rootNode
, weakShell
);
456 *aRootAcc
= new nsRootAccessibleWrap(rootNode
, weakShell
);
459 return NS_ERROR_OUT_OF_MEMORY
;
461 nsRefPtr
<nsAccessNode
> rootAcc
= nsAccUtils::QueryAccessNode(*aRootAcc
);
464 nsRoleMapEntry
*roleMapEntry
= nsAccUtils::GetRoleMapEntry(rootNode
);
465 nsCOMPtr
<nsPIAccessible
> privateAccessible(do_QueryInterface(*aRootAcc
));
466 privateAccessible
->SetRoleMapEntry(roleMapEntry
);
468 NS_ADDREF(*aRootAcc
);
474 * HTML widget creation
477 nsAccessibilityService::CreateHTML4ButtonAccessible(nsISupports
*aFrame
, nsIAccessible
**_retval
)
480 nsCOMPtr
<nsIDOMNode
> node
;
481 nsCOMPtr
<nsIWeakReference
> weakShell
;
482 nsresult rv
= GetInfo(aFrame
, &frame
, getter_AddRefs(weakShell
), getter_AddRefs(node
));
486 *_retval
= new nsHTML4ButtonAccessible(node
, weakShell
);
488 return NS_ERROR_OUT_OF_MEMORY
;
495 nsAccessibilityService::CreateHTMLButtonAccessible(nsISupports
*aFrame
, nsIAccessible
**_retval
)
498 nsCOMPtr
<nsIDOMNode
> node
;
499 nsCOMPtr
<nsIWeakReference
> weakShell
;
500 nsresult rv
= GetInfo(aFrame
, &frame
, getter_AddRefs(weakShell
), getter_AddRefs(node
));
504 *_retval
= new nsHTMLButtonAccessible(node
, weakShell
);
506 return NS_ERROR_OUT_OF_MEMORY
;
513 nsAccessibilityService::CreateHTMLAccessibleByMarkup(nsIFrame
*aFrame
,
514 nsIWeakReference
*aWeakShell
,
516 nsIAccessible
**aAccessible
)
518 // This method assumes we're in an HTML namespace.
519 *aAccessible
= nsnull
;
520 nsCOMPtr
<nsIContent
> content(do_QueryInterface(aNode
));
521 nsIAtom
*tag
= content
->Tag();
522 if (tag
== nsAccessibilityAtoms::legend
) {
523 *aAccessible
= new nsHTMLLegendAccessible(aNode
, aWeakShell
);
525 else if (tag
== nsAccessibilityAtoms::option
) {
526 *aAccessible
= new nsHTMLSelectOptionAccessible(aNode
, aWeakShell
);
528 else if (tag
== nsAccessibilityAtoms::optgroup
) {
529 *aAccessible
= new nsHTMLSelectOptGroupAccessible(aNode
, aWeakShell
);
531 else if (tag
== nsAccessibilityAtoms::ul
|| tag
== nsAccessibilityAtoms::ol
) {
532 *aAccessible
= new nsHTMLListAccessible(aNode
, aWeakShell
);
534 else if (tag
== nsAccessibilityAtoms::a
) {
535 *aAccessible
= new nsHTMLLinkAccessible(aNode
, aWeakShell
);
537 else if (tag
== nsAccessibilityAtoms::li
&& aFrame
->GetType() != nsAccessibilityAtoms::blockFrame
) {
538 // Normally this is created by the list item frame which knows about the bullet frame
539 // However, in this case the list item must have been styled using display: foo
540 *aAccessible
= new nsHTMLLIAccessible(aNode
, aWeakShell
, EmptyString());
542 else if (tag
== nsAccessibilityAtoms::abbr
||
543 tag
== nsAccessibilityAtoms::acronym
||
544 tag
== nsAccessibilityAtoms::blockquote
||
545 tag
== nsAccessibilityAtoms::dd
||
546 tag
== nsAccessibilityAtoms::dl
||
547 tag
== nsAccessibilityAtoms::dt
||
548 tag
== nsAccessibilityAtoms::form
||
549 tag
== nsAccessibilityAtoms::h1
||
550 tag
== nsAccessibilityAtoms::h2
||
551 tag
== nsAccessibilityAtoms::h3
||
552 tag
== nsAccessibilityAtoms::h4
||
553 tag
== nsAccessibilityAtoms::h5
||
554 tag
== nsAccessibilityAtoms::h6
||
555 #ifndef MOZ_ACCESSIBILITY_ATK
556 tag
== nsAccessibilityAtoms::tbody
||
557 tag
== nsAccessibilityAtoms::tfoot
||
558 tag
== nsAccessibilityAtoms::thead
||
560 tag
== nsAccessibilityAtoms::q
) {
561 return CreateHyperTextAccessible(aFrame
, aAccessible
);
563 NS_IF_ADDREF(*aAccessible
);
568 nsAccessibilityService::CreateHTMLLIAccessible(nsISupports
*aFrame
,
569 nsISupports
*aBulletFrame
,
570 const nsAString
& aBulletText
,
571 nsIAccessible
**_retval
)
574 nsCOMPtr
<nsIDOMNode
> node
;
575 nsCOMPtr
<nsIWeakReference
> weakShell
;
576 nsresult rv
= GetInfo(aFrame
, &frame
, getter_AddRefs(weakShell
), getter_AddRefs(node
));
580 *_retval
= new nsHTMLLIAccessible(node
, weakShell
, aBulletText
);
582 return NS_ERROR_OUT_OF_MEMORY
;
589 nsAccessibilityService::CreateHyperTextAccessible(nsISupports
*aFrame
, nsIAccessible
**aAccessible
)
592 nsCOMPtr
<nsIDOMNode
> node
;
593 nsCOMPtr
<nsIWeakReference
> weakShell
;
594 nsresult rv
= GetInfo(aFrame
, &frame
, getter_AddRefs(weakShell
), getter_AddRefs(node
));
598 nsCOMPtr
<nsIContent
> content(do_QueryInterface(node
));
599 NS_ENSURE_TRUE(content
, NS_ERROR_FAILURE
);
601 *aAccessible
= new nsHyperTextAccessibleWrap(node
, weakShell
);
602 NS_ENSURE_TRUE(*aAccessible
, NS_ERROR_OUT_OF_MEMORY
);
604 NS_ADDREF(*aAccessible
);
609 nsAccessibilityService::CreateHTMLCheckboxAccessible(nsISupports
*aFrame
, nsIAccessible
**_retval
)
612 nsCOMPtr
<nsIDOMNode
> node
;
613 nsCOMPtr
<nsIWeakReference
> weakShell
;
614 nsresult rv
= GetInfo(aFrame
, &frame
, getter_AddRefs(weakShell
), getter_AddRefs(node
));
618 *_retval
= new nsHTMLCheckboxAccessible(node
, weakShell
);
620 return NS_ERROR_OUT_OF_MEMORY
;
627 nsAccessibilityService::CreateHTMLComboboxAccessible(nsIDOMNode
* aDOMNode
, nsIWeakReference
* aPresShell
, nsIAccessible
**_retval
)
629 *_retval
= new nsHTMLComboboxAccessible(aDOMNode
, aPresShell
);
631 return NS_ERROR_OUT_OF_MEMORY
;
638 nsAccessibilityService::CreateHTMLImageAccessible(nsISupports
*aFrame
, nsIAccessible
**_retval
)
641 nsCOMPtr
<nsIDOMNode
> node
;
642 nsCOMPtr
<nsIWeakReference
> weakShell
;
643 nsresult rv
= GetInfo(aFrame
, &frame
, getter_AddRefs(weakShell
), getter_AddRefs(node
));
648 nsCOMPtr
<nsIDOMElement
> domElement(do_QueryInterface(node
));
650 *_retval
= new nsHTMLImageAccessibleWrap(node
, weakShell
);
654 return NS_ERROR_OUT_OF_MEMORY
;
661 nsAccessibilityService::CreateHTMLGenericAccessible(nsISupports
*aFrame
, nsIAccessible
**aAccessible
)
663 return CreateHyperTextAccessible(aFrame
, aAccessible
);
667 nsAccessibilityService::CreateHTMLGroupboxAccessible(nsISupports
*aFrame
, nsIAccessible
**_retval
)
670 nsCOMPtr
<nsIDOMNode
> node
;
671 nsCOMPtr
<nsIWeakReference
> weakShell
;
672 nsresult rv
= GetInfo(aFrame
, &frame
, getter_AddRefs(weakShell
), getter_AddRefs(node
));
676 *_retval
= new nsHTMLGroupboxAccessible(node
, weakShell
);
678 return NS_ERROR_OUT_OF_MEMORY
;
685 nsAccessibilityService::CreateHTMLListboxAccessible(nsIDOMNode
* aDOMNode
, nsIWeakReference
* aPresShell
, nsIAccessible
**_retval
)
687 *_retval
= new nsHTMLSelectListAccessible(aDOMNode
, aPresShell
);
689 return NS_ERROR_OUT_OF_MEMORY
;
696 * We can have several cases here.
697 * 1) a text or html embedded document where the contentDocument
698 * variable in the object element holds the content
699 * 2) web content that uses a plugin, which means we will
700 * have to go to the plugin to get the accessible content
701 * 3) An image or imagemap, where the image frame points back to
702 * the object element DOMNode
705 nsAccessibilityService::CreateHTMLObjectFrameAccessible(nsObjectFrame
*aFrame
,
706 nsIAccessible
**aAccessible
)
708 nsCOMPtr
<nsIDOMNode
> node
;
709 nsCOMPtr
<nsIWeakReference
> weakShell
;
711 GetInfo(static_cast<nsIFrame
*>(aFrame
), &frame
, getter_AddRefs(weakShell
), getter_AddRefs(node
));
713 *aAccessible
= nsnull
;
714 if (!frame
|| frame
->GetRect().IsEmpty()) {
715 return NS_ERROR_FAILURE
;
717 // 1) for object elements containing either HTML or TXT documents
718 nsCOMPtr
<nsIDOMDocument
> domDoc
;
719 nsCOMPtr
<nsIDOMHTMLObjectElement
> obj(do_QueryInterface(node
));
721 obj
->GetContentDocument(getter_AddRefs(domDoc
));
723 domDoc
= do_QueryInterface(node
);
725 return CreateOuterDocAccessible(node
, aAccessible
);
729 nsCOMPtr
<nsIPluginInstance
> pluginInstance
;
730 aFrame
->GetPluginInstance(*getter_AddRefs(pluginInstance
));
731 if (pluginInstance
) {
732 HWND pluginPort
= nsnull
;
733 aFrame
->GetPluginPort(&pluginPort
);
735 *aAccessible
= new nsHTMLWin32ObjectOwnerAccessible(node
, weakShell
, pluginPort
);
737 NS_ADDREF(*aAccessible
);
744 // 3) for images and imagemaps, or anything else with a child frame
745 // we have the object frame, get the image frame
746 frame
= aFrame
->GetFirstChild(nsnull
);
748 return frame
->GetAccessible(aAccessible
);
754 nsAccessibilityService::CreateHTMLRadioButtonAccessible(nsISupports
*aFrame
, nsIAccessible
**_retval
)
757 nsCOMPtr
<nsIDOMNode
> node
;
758 nsCOMPtr
<nsIWeakReference
> weakShell
;
759 nsresult rv
= GetInfo(aFrame
, &frame
, getter_AddRefs(weakShell
), getter_AddRefs(node
));
763 *_retval
= new nsHTMLRadioButtonAccessible(node
, weakShell
);
765 return NS_ERROR_OUT_OF_MEMORY
;
772 nsAccessibilityService::CreateHTMLSelectOptionAccessible(nsIDOMNode
* aDOMNode
,
773 nsIAccessible
*aParent
,
774 nsIWeakReference
* aPresShell
,
775 nsIAccessible
**_retval
)
777 *_retval
= new nsHTMLSelectOptionAccessible(aDOMNode
, aPresShell
);
779 return NS_ERROR_OUT_OF_MEMORY
;
786 nsAccessibilityService::CreateHTMLTableAccessible(nsISupports
*aFrame
, nsIAccessible
**_retval
)
789 nsCOMPtr
<nsIDOMNode
> node
;
790 nsCOMPtr
<nsIWeakReference
> weakShell
;
791 nsresult rv
= GetInfo(aFrame
, &frame
, getter_AddRefs(weakShell
), getter_AddRefs(node
));
795 *_retval
= new nsHTMLTableAccessibleWrap(node
, weakShell
);
797 return NS_ERROR_OUT_OF_MEMORY
;
804 nsAccessibilityService::CreateHTMLTableHeadAccessible(nsIDOMNode
*aDOMNode
, nsIAccessible
**_retval
)
806 #ifndef MOZ_ACCESSIBILITY_ATK
808 return NS_ERROR_FAILURE
;
810 NS_ENSURE_ARG_POINTER(aDOMNode
);
814 nsCOMPtr
<nsIWeakReference
> weakShell
;
815 rv
= GetShellFromNode(aDOMNode
, getter_AddRefs(weakShell
));
816 NS_ENSURE_SUCCESS(rv
, rv
);
818 nsHTMLTableHeadAccessibleWrap
* accTableHead
=
819 new nsHTMLTableHeadAccessibleWrap(aDOMNode
, weakShell
);
821 NS_ENSURE_TRUE(accTableHead
, NS_ERROR_OUT_OF_MEMORY
);
823 *_retval
= static_cast<nsIAccessible
*>(accTableHead
);
824 NS_IF_ADDREF(*_retval
);
831 nsAccessibilityService::CreateHTMLTableCellAccessible(nsISupports
*aFrame
, nsIAccessible
**_retval
)
834 nsCOMPtr
<nsIDOMNode
> node
;
835 nsCOMPtr
<nsIWeakReference
> weakShell
;
836 nsresult rv
= GetInfo(aFrame
, &frame
, getter_AddRefs(weakShell
), getter_AddRefs(node
));
840 *_retval
= new nsHTMLTableCellAccessible(node
, weakShell
);
842 return NS_ERROR_OUT_OF_MEMORY
;
849 nsAccessibilityService::CreateHTMLTextAccessible(nsISupports
*aFrame
, nsIAccessible
**_retval
)
854 nsCOMPtr
<nsIDOMNode
> node
;
855 nsCOMPtr
<nsIWeakReference
> weakShell
;
856 nsresult rv
= GetInfo(aFrame
, &frame
, getter_AddRefs(weakShell
), getter_AddRefs(node
));
860 // XXX Don't create ATK objects for these
861 *_retval
= new nsHTMLTextAccessible(node
, weakShell
);
863 return NS_ERROR_OUT_OF_MEMORY
;
870 nsAccessibilityService::CreateHTMLTextFieldAccessible(nsISupports
*aFrame
, nsIAccessible
**_retval
)
873 nsCOMPtr
<nsIDOMNode
> node
;
874 nsCOMPtr
<nsIWeakReference
> weakShell
;
875 nsresult rv
= GetInfo(aFrame
, &frame
, getter_AddRefs(weakShell
), getter_AddRefs(node
));
879 *_retval
= new nsHTMLTextFieldAccessible(node
, weakShell
);
881 return NS_ERROR_OUT_OF_MEMORY
;
888 nsAccessibilityService::CreateHTMLLabelAccessible(nsISupports
*aFrame
, nsIAccessible
**_retval
)
891 nsCOMPtr
<nsIDOMNode
> node
;
892 nsCOMPtr
<nsIWeakReference
> weakShell
;
893 nsresult rv
= GetInfo(aFrame
, &frame
, getter_AddRefs(weakShell
), getter_AddRefs(node
));
897 *_retval
= new nsHTMLLabelAccessible(node
, weakShell
);
899 return NS_ERROR_OUT_OF_MEMORY
;
906 nsAccessibilityService::CreateHTMLHRAccessible(nsISupports
*aFrame
, nsIAccessible
**_retval
)
909 nsCOMPtr
<nsIDOMNode
> node
;
910 nsCOMPtr
<nsIWeakReference
> weakShell
;
911 nsresult rv
= GetInfo(aFrame
, &frame
, getter_AddRefs(weakShell
), getter_AddRefs(node
));
915 *_retval
= new nsHTMLHRAccessible(node
, weakShell
);
917 return NS_ERROR_OUT_OF_MEMORY
;
924 nsAccessibilityService::CreateHTMLBRAccessible(nsISupports
*aFrame
, nsIAccessible
**_retval
)
927 nsCOMPtr
<nsIDOMNode
> node
;
928 nsCOMPtr
<nsIWeakReference
> weakShell
;
929 nsresult rv
= GetInfo(aFrame
, &frame
, getter_AddRefs(weakShell
), getter_AddRefs(node
));
933 *_retval
= new nsHTMLBRAccessible(node
, weakShell
);
935 return NS_ERROR_OUT_OF_MEMORY
;
942 nsAccessibilityService::CreateHTMLCaptionAccessible(nsISupports
*aFrame
, nsIAccessible
**_retval
)
945 nsCOMPtr
<nsIDOMNode
> node
;
946 nsCOMPtr
<nsIWeakReference
> weakShell
;
947 nsresult rv
= GetInfo(aFrame
, &frame
, getter_AddRefs(weakShell
), getter_AddRefs(node
));
951 *_retval
= new nsHTMLCaptionAccessible(node
, weakShell
);
953 return NS_ERROR_OUT_OF_MEMORY
;
959 NS_IMETHODIMP
nsAccessibilityService::GetCachedAccessible(nsIDOMNode
*aNode
,
960 nsIWeakReference
*aWeakShell
,
961 nsIAccessible
**aAccessible
)
963 nsCOMPtr
<nsIAccessNode
> accessNode
;
964 nsresult rv
= GetCachedAccessNode(aNode
, aWeakShell
, getter_AddRefs(accessNode
));
965 nsCOMPtr
<nsIAccessible
> accessible(do_QueryInterface(accessNode
));
966 NS_IF_ADDREF(*aAccessible
= accessible
);
970 NS_IMETHODIMP
nsAccessibilityService::GetCachedAccessNode(nsIDOMNode
*aNode
,
971 nsIWeakReference
*aWeakShell
,
972 nsIAccessNode
**aAccessNode
)
974 nsCOMPtr
<nsIAccessibleDocument
> accessibleDoc
=
975 nsAccessNode::GetDocAccessibleFor(aWeakShell
);
977 if (!accessibleDoc
) {
978 *aAccessNode
= nsnull
;
979 return NS_ERROR_FAILURE
;
982 return accessibleDoc
->GetCachedAccessNode(static_cast<void*>(aNode
), aAccessNode
);
986 nsAccessibilityService::GetStringRole(PRUint32 aRole
, nsAString
& aString
)
988 if ( aRole
>= NS_ARRAY_LENGTH(kRoleNames
)) {
989 aString
.AssignLiteral("unknown");
993 CopyUTF8toUTF16(kRoleNames
[aRole
], aString
);
998 nsAccessibilityService::GetStringStates(PRUint32 aStates
, PRUint32 aExtraStates
,
999 nsIDOMDOMStringList
**aStringStates
)
1001 nsAccessibleDOMStringList
*stringStates
= new nsAccessibleDOMStringList();
1002 NS_ENSURE_TRUE(stringStates
, NS_ERROR_OUT_OF_MEMORY
);
1005 if (aStates
& nsIAccessibleStates::STATE_UNAVAILABLE
)
1006 stringStates
->Add(NS_LITERAL_STRING("unavailable"));
1007 if (aStates
& nsIAccessibleStates::STATE_SELECTED
)
1008 stringStates
->Add(NS_LITERAL_STRING("selected"));
1009 if (aStates
& nsIAccessibleStates::STATE_FOCUSED
)
1010 stringStates
->Add(NS_LITERAL_STRING("focused"));
1011 if (aStates
& nsIAccessibleStates::STATE_PRESSED
)
1012 stringStates
->Add(NS_LITERAL_STRING("pressed"));
1013 if (aStates
& nsIAccessibleStates::STATE_CHECKED
)
1014 stringStates
->Add(NS_LITERAL_STRING("checked"));
1015 if (aStates
& nsIAccessibleStates::STATE_MIXED
)
1016 stringStates
->Add(NS_LITERAL_STRING("mixed"));
1017 if (aStates
& nsIAccessibleStates::STATE_READONLY
)
1018 stringStates
->Add(NS_LITERAL_STRING("readonly"));
1019 if (aStates
& nsIAccessibleStates::STATE_HOTTRACKED
)
1020 stringStates
->Add(NS_LITERAL_STRING("hottracked"));
1021 if (aStates
& nsIAccessibleStates::STATE_DEFAULT
)
1022 stringStates
->Add(NS_LITERAL_STRING("default"));
1023 if (aStates
& nsIAccessibleStates::STATE_EXPANDED
)
1024 stringStates
->Add(NS_LITERAL_STRING("expanded"));
1025 if (aStates
& nsIAccessibleStates::STATE_COLLAPSED
)
1026 stringStates
->Add(NS_LITERAL_STRING("collapsed"));
1027 if (aStates
& nsIAccessibleStates::STATE_BUSY
)
1028 stringStates
->Add(NS_LITERAL_STRING("busy"));
1029 if (aStates
& nsIAccessibleStates::STATE_FLOATING
)
1030 stringStates
->Add(NS_LITERAL_STRING("floating"));
1031 if (aStates
& nsIAccessibleStates::STATE_ANIMATED
)
1032 stringStates
->Add(NS_LITERAL_STRING("animated"));
1033 if (aStates
& nsIAccessibleStates::STATE_INVISIBLE
)
1034 stringStates
->Add(NS_LITERAL_STRING("invisible"));
1035 if (aStates
& nsIAccessibleStates::STATE_OFFSCREEN
)
1036 stringStates
->Add(NS_LITERAL_STRING("offscreen"));
1037 if (aStates
& nsIAccessibleStates::STATE_SIZEABLE
)
1038 stringStates
->Add(NS_LITERAL_STRING("sizeable"));
1039 if (aStates
& nsIAccessibleStates::STATE_MOVEABLE
)
1040 stringStates
->Add(NS_LITERAL_STRING("moveable"));
1041 if (aStates
& nsIAccessibleStates::STATE_SELFVOICING
)
1042 stringStates
->Add(NS_LITERAL_STRING("selfvoicing"));
1043 if (aStates
& nsIAccessibleStates::STATE_FOCUSABLE
)
1044 stringStates
->Add(NS_LITERAL_STRING("focusable"));
1045 if (aStates
& nsIAccessibleStates::STATE_SELECTABLE
)
1046 stringStates
->Add(NS_LITERAL_STRING("selectable"));
1047 if (aStates
& nsIAccessibleStates::STATE_LINKED
)
1048 stringStates
->Add(NS_LITERAL_STRING("linked"));
1049 if (aStates
& nsIAccessibleStates::STATE_TRAVERSED
)
1050 stringStates
->Add(NS_LITERAL_STRING("traversed"));
1051 if (aStates
& nsIAccessibleStates::STATE_MULTISELECTABLE
)
1052 stringStates
->Add(NS_LITERAL_STRING("multiselectable"));
1053 if (aStates
& nsIAccessibleStates::STATE_EXTSELECTABLE
)
1054 stringStates
->Add(NS_LITERAL_STRING("extselectable"));
1055 if (aStates
& nsIAccessibleStates::STATE_PROTECTED
)
1056 stringStates
->Add(NS_LITERAL_STRING("protected"));
1057 if (aStates
& nsIAccessibleStates::STATE_HASPOPUP
)
1058 stringStates
->Add(NS_LITERAL_STRING("haspopup"));
1059 if (aStates
& nsIAccessibleStates::STATE_REQUIRED
)
1060 stringStates
->Add(NS_LITERAL_STRING("required"));
1061 if (aStates
& nsIAccessibleStates::STATE_IMPORTANT
)
1062 stringStates
->Add(NS_LITERAL_STRING("important"));
1063 if (aStates
& nsIAccessibleStates::STATE_INVALID
)
1064 stringStates
->Add(NS_LITERAL_STRING("invalid"));
1065 if (aStates
& nsIAccessibleStates::STATE_CHECKABLE
)
1066 stringStates
->Add(NS_LITERAL_STRING("checkable"));
1069 if (aExtraStates
& nsIAccessibleStates::EXT_STATE_SUPPORTS_AUTOCOMPLETION
)
1070 stringStates
->Add(NS_LITERAL_STRING("autocompletion"));
1071 if (aExtraStates
& nsIAccessibleStates::EXT_STATE_DEFUNCT
)
1072 stringStates
->Add(NS_LITERAL_STRING("defunct"));
1073 if (aExtraStates
& nsIAccessibleStates::EXT_STATE_SELECTABLE_TEXT
)
1074 stringStates
->Add(NS_LITERAL_STRING("selectable text"));
1075 if (aExtraStates
& nsIAccessibleStates::EXT_STATE_EDITABLE
)
1076 stringStates
->Add(NS_LITERAL_STRING("editable"));
1077 if (aExtraStates
& nsIAccessibleStates::EXT_STATE_ACTIVE
)
1078 stringStates
->Add(NS_LITERAL_STRING("active"));
1079 if (aExtraStates
& nsIAccessibleStates::EXT_STATE_MODAL
)
1080 stringStates
->Add(NS_LITERAL_STRING("modal"));
1081 if (aExtraStates
& nsIAccessibleStates::EXT_STATE_MULTI_LINE
)
1082 stringStates
->Add(NS_LITERAL_STRING("multi line"));
1083 if (aExtraStates
& nsIAccessibleStates::EXT_STATE_HORIZONTAL
)
1084 stringStates
->Add(NS_LITERAL_STRING("horizontal"));
1085 if (aExtraStates
& nsIAccessibleStates::EXT_STATE_OPAQUE
)
1086 stringStates
->Add(NS_LITERAL_STRING("opaque"));
1087 if (aExtraStates
& nsIAccessibleStates::EXT_STATE_SINGLE_LINE
)
1088 stringStates
->Add(NS_LITERAL_STRING("single line"));
1089 if (aExtraStates
& nsIAccessibleStates::EXT_STATE_TRANSIENT
)
1090 stringStates
->Add(NS_LITERAL_STRING("transient"));
1091 if (aExtraStates
& nsIAccessibleStates::EXT_STATE_VERTICAL
)
1092 stringStates
->Add(NS_LITERAL_STRING("vertical"));
1093 if (aExtraStates
& nsIAccessibleStates::EXT_STATE_STALE
)
1094 stringStates
->Add(NS_LITERAL_STRING("stale"));
1095 if (aExtraStates
& nsIAccessibleStates::EXT_STATE_ENABLED
)
1096 stringStates
->Add(NS_LITERAL_STRING("enabled"));
1097 if (aExtraStates
& nsIAccessibleStates::EXT_STATE_SENSITIVE
)
1098 stringStates
->Add(NS_LITERAL_STRING("sensitive"));
1099 if (aExtraStates
& nsIAccessibleStates::EXT_STATE_EXPANDABLE
)
1100 stringStates
->Add(NS_LITERAL_STRING("expandable"));
1103 PRUint32 stringStatesLength
= 0;
1105 stringStates
->GetLength(&stringStatesLength
);
1106 if (!stringStatesLength
)
1107 stringStates
->Add(NS_LITERAL_STRING("unknown"));
1109 NS_ADDREF(*aStringStates
= stringStates
);
1113 // nsIAccessibleRetrieval::getStringEventType()
1115 nsAccessibilityService::GetStringEventType(PRUint32 aEventType
,
1118 NS_ASSERTION(nsIAccessibleEvent::EVENT_LAST_ENTRY
== NS_ARRAY_LENGTH(kEventTypeNames
),
1119 "nsIAccessibleEvent constants are out of sync to kEventTypeNames");
1121 if (aEventType
>= NS_ARRAY_LENGTH(kEventTypeNames
)) {
1122 aString
.AssignLiteral("unknown");
1126 CopyUTF8toUTF16(kEventTypeNames
[aEventType
], aString
);
1130 // nsIAccessibleRetrieval::getStringRelationType()
1132 nsAccessibilityService::GetStringRelationType(PRUint32 aRelationType
,
1135 if (aRelationType
>= NS_ARRAY_LENGTH(kRelationTypeNames
)) {
1136 aString
.AssignLiteral("unknown");
1140 CopyUTF8toUTF16(kRelationTypeNames
[aRelationType
], aString
);
1146 * GetAccessibleFor - get an nsIAccessible from a DOM node
1150 nsAccessibilityService::GetAccessibleFor(nsIDOMNode
*aNode
,
1151 nsIAccessible
**aAccessible
)
1153 NS_ENSURE_ARG_POINTER(aAccessible
);
1154 *aAccessible
= nsnull
;
1156 NS_ENSURE_ARG(aNode
);
1158 // We use presentation shell #0 because we assume that is presentation of
1159 // given node window.
1160 nsCOMPtr
<nsIContent
> content(do_QueryInterface(aNode
));
1161 nsCOMPtr
<nsIDocument
> doc
;
1163 doc
= content
->GetDocument();
1165 else {// Could be document node
1166 doc
= do_QueryInterface(aNode
);
1169 return NS_ERROR_FAILURE
;
1171 nsIPresShell
*presShell
= doc
->GetPrimaryShell();
1172 return GetAccessibleInShell(aNode
, presShell
, aAccessible
);
1176 nsAccessibilityService::GetAttachedAccessibleFor(nsIDOMNode
*aNode
,
1177 nsIAccessible
**aAccessible
)
1179 NS_ENSURE_ARG(aNode
);
1180 NS_ENSURE_ARG_POINTER(aAccessible
);
1182 *aAccessible
= nsnull
;
1184 nsCOMPtr
<nsIDOMNode
> relevantNode
;
1185 nsresult rv
= GetRelevantContentNodeFor(aNode
, getter_AddRefs(relevantNode
));
1186 NS_ENSURE_SUCCESS(rv
, rv
);
1188 if (relevantNode
!= aNode
)
1191 return GetAccessibleFor(aNode
, aAccessible
);
1194 NS_IMETHODIMP
nsAccessibilityService::GetAccessibleInWindow(nsIDOMNode
*aNode
,
1196 nsIAccessible
**aAccessible
)
1198 NS_ENSURE_ARG_POINTER(aAccessible
);
1199 *aAccessible
= nsnull
;
1201 NS_ENSURE_ARG(aNode
);
1202 NS_ENSURE_ARG(aWin
);
1204 nsCOMPtr
<nsIWebNavigation
> webNav(do_GetInterface(aWin
));
1205 nsCOMPtr
<nsIDocShell
> docShell(do_QueryInterface(webNav
));
1207 return NS_ERROR_FAILURE
;
1209 nsCOMPtr
<nsIPresShell
> presShell
;
1210 docShell
->GetPresShell(getter_AddRefs(presShell
));
1211 return GetAccessibleInShell(aNode
, presShell
, aAccessible
);
1214 NS_IMETHODIMP
nsAccessibilityService::GetAccessibleInShell(nsIDOMNode
*aNode
,
1215 nsIPresShell
*aPresShell
,
1216 nsIAccessible
**aAccessible
)
1218 NS_ENSURE_ARG_POINTER(aAccessible
);
1219 *aAccessible
= nsnull
;
1221 NS_ENSURE_ARG(aNode
);
1222 NS_ENSURE_ARG(aPresShell
);
1224 nsCOMPtr
<nsIWeakReference
> weakShell(do_GetWeakReference(aPresShell
));
1225 nsIFrame
*outFrameUnused
= NULL
;
1226 PRBool isHiddenUnused
= false;
1227 return GetAccessible(aNode
, aPresShell
, weakShell
,
1228 &outFrameUnused
, &isHiddenUnused
, aAccessible
);
1231 NS_IMETHODIMP
nsAccessibilityService::GetAccessibleInWeakShell(nsIDOMNode
*aNode
,
1232 nsIWeakReference
*aWeakShell
,
1233 nsIAccessible
**aAccessible
)
1235 NS_ENSURE_ARG_POINTER(aAccessible
);
1236 *aAccessible
= nsnull
;
1238 NS_ENSURE_ARG(aNode
);
1239 NS_ENSURE_ARG(aWeakShell
);
1241 nsCOMPtr
<nsIPresShell
> presShell(do_QueryReferent(aWeakShell
));
1242 nsIFrame
*outFrameUnused
= NULL
;
1243 PRBool isHiddenUnused
= false;
1244 return GetAccessible(aNode
, presShell
, aWeakShell
,
1245 &outFrameUnused
, &isHiddenUnused
, aAccessible
);
1248 nsresult
nsAccessibilityService::InitAccessible(nsIAccessible
*aAccessibleIn
,
1249 nsIAccessible
**aAccessibleOut
,
1250 nsRoleMapEntry
*aRoleMapEntry
)
1252 if (!aAccessibleIn
) {
1253 return NS_ERROR_FAILURE
; // No accessible to init
1255 NS_ASSERTION(aAccessibleOut
&& !*aAccessibleOut
, "Out param should already be cleared out");
1257 nsRefPtr
<nsAccessNode
> acc
= nsAccUtils::QueryAccessNode(aAccessibleIn
);
1258 nsresult rv
= acc
->Init(); // Add to cache, etc.
1259 NS_ENSURE_SUCCESS(rv
, rv
);
1261 nsCOMPtr
<nsPIAccessible
> privateAccessible
=
1262 do_QueryInterface(aAccessibleIn
);
1263 privateAccessible
->SetRoleMapEntry(aRoleMapEntry
);
1264 NS_ADDREF(*aAccessibleOut
= aAccessibleIn
);
1269 static PRBool
HasRelatedContent(nsIContent
*aContent
)
1272 if (!aContent
|| !nsCoreUtils::GetID(aContent
, id
) || id
.IsEmpty()) {
1276 nsIAtom
*relationAttrs
[] = {nsAccessibilityAtoms::aria_labelledby
,
1277 nsAccessibilityAtoms::aria_describedby
,
1278 nsAccessibilityAtoms::aria_owns
,
1279 nsAccessibilityAtoms::aria_controls
,
1280 nsAccessibilityAtoms::aria_flowto
};
1281 if (nsCoreUtils::FindNeighbourPointingToNode(aContent
, relationAttrs
,
1282 NS_ARRAY_LENGTH(relationAttrs
))) {
1286 nsIContent
*ancestorContent
= aContent
;
1287 while ((ancestorContent
= ancestorContent
->GetParent()) != nsnull
) {
1288 if (ancestorContent
->HasAttr(kNameSpaceID_None
, nsAccessibilityAtoms::aria_activedescendant
)) {
1289 // ancestor has activedescendant property, this content could be active
1297 NS_IMETHODIMP
nsAccessibilityService::GetAccessible(nsIDOMNode
*aNode
,
1298 nsIPresShell
*aPresShell
,
1299 nsIWeakReference
*aWeakShell
,
1300 nsIFrame
**aFrameHint
,
1302 nsIAccessible
**aAccessible
)
1304 NS_ENSURE_ARG_POINTER(aAccessible
);
1305 NS_ENSURE_ARG_POINTER(aFrameHint
);
1306 *aAccessible
= nsnull
;
1307 if (!aPresShell
|| !aWeakShell
) {
1308 return NS_ERROR_FAILURE
;
1311 NS_ASSERTION(aNode
, "GetAccessible() called with no node.");
1313 *aIsHidden
= PR_FALSE
;
1316 // Please leave this in for now, it's a convenient debugging method
1318 aNode
->GetLocalName(name
);
1319 if (name
.LowerCaseEqualsLiteral("h1"))
1320 printf("## aaronl debugging tag name\n");
1322 nsAutoString attrib
;
1323 nsCOMPtr
<nsIDOMElement
> element(do_QueryInterface(aNode
));
1325 element
->GetAttribute(NS_LITERAL_STRING("type"), attrib
);
1326 if (attrib
.EqualsLiteral("statusbarpanel"))
1327 printf("## aaronl debugging attribute\n");
1331 // Check to see if we already have an accessible for this
1332 // node in the cache
1333 nsCOMPtr
<nsIAccessNode
> accessNode
;
1334 GetCachedAccessNode(aNode
, aWeakShell
, getter_AddRefs(accessNode
));
1336 nsCOMPtr
<nsIAccessible
> newAcc
;
1338 // Retrieved from cache. QI might not succeed if it's a node that's not
1339 // accessible. In this case try to create new accessible because one and
1340 // the same DOM node may be accessible or not in time (for example,
1341 // when it is visible or hidden).
1342 newAcc
= do_QueryInterface(accessNode
);
1344 NS_ADDREF(*aAccessible
= newAcc
);
1349 nsCOMPtr
<nsIContent
> content(do_QueryInterface(aNode
));
1351 // No cache entry, so we must create the accessible
1352 // Check to see if hidden first
1353 nsCOMPtr
<nsIDocument
> nodeIsDoc
;
1355 // This happens when we're on the document node, which will not QI to an
1357 nodeIsDoc
= do_QueryInterface(aNode
);
1358 NS_ENSURE_TRUE(nodeIsDoc
, NS_ERROR_FAILURE
); // No content, and not doc node
1360 nsCOMPtr
<nsIAccessibleDocument
> accessibleDoc
=
1361 nsAccessNode::GetDocAccessibleFor(aWeakShell
);
1362 if (accessibleDoc
) {
1363 newAcc
= do_QueryInterface(accessibleDoc
);
1364 NS_ASSERTION(newAcc
, "nsIAccessibleDocument is not an nsIAccessible");
1367 CreateRootAccessible(aPresShell
, nodeIsDoc
, getter_AddRefs(newAcc
)); // Does Init() for us
1370 *aFrameHint
= aPresShell
->GetRootFrame();
1371 NS_IF_ADDREF(*aAccessible
= newAcc
);
1375 NS_ASSERTION(content
->GetDocument(), "Creating accessible for node with no document");
1376 if (!content
->GetDocument()) {
1377 return NS_ERROR_FAILURE
;
1379 NS_ASSERTION(content
->GetDocument() == aPresShell
->GetDocument(), "Creating accessible for wrong pres shell");
1380 if (content
->GetDocument() != aPresShell
->GetDocument()) {
1381 return NS_ERROR_FAILURE
;
1384 // We have a content node
1385 nsIFrame
*frame
= *aFrameHint
;
1387 static int frameHintFailed
, frameHintTried
, frameHintNonexistant
, frameHintFailedForText
;
1390 if (!frame
|| content
!= frame
->GetContent()) {
1391 // Frame hint not correct, get true frame, we try to optimize away from this
1392 frame
= aPresShell
->GetRealPrimaryFrameFor(content
);
1394 #ifdef DEBUG_A11Y_FRAME_OPTIMIZATION
1395 // Frame hint debugging
1397 if (content
->IsNodeOfType(nsINode::eTEXT
)) {
1398 ++frameHintFailedForText
;
1400 frameHintNonexistant
+= !*aFrameHint
;
1401 printf("Frame hint failures: %d / %d . Text fails = %d. No hint fails = %d \n", frameHintFailed
, frameHintTried
, frameHintFailedForText
, frameHintNonexistant
);
1402 if (frameHintTried
>= 354) {
1403 printf("* "); // Aaron's break point
1406 if (frame
->GetContent() != content
) {
1407 // Not the main content for this frame!
1408 // For example, this happens because <area> elements return the
1409 // image frame as their primary frame. The main content for the
1410 // image frame is the image content.
1412 // Check if frame is an image frame, and content is <area>
1413 nsIImageFrame
*imageFrame
;
1414 CallQueryInterface(frame
, &imageFrame
);
1415 nsCOMPtr
<nsIDOMHTMLAreaElement
> areaElmt
= do_QueryInterface(content
);
1416 if (imageFrame
&& areaElmt
) {
1417 nsCOMPtr
<nsIAccessible
> imageAcc
;
1418 CreateHTMLImageAccessible(frame
, getter_AddRefs(imageAcc
));
1422 imageAcc
->GetChildCount(&childCount
);
1423 // area accessible should be in cache now
1424 return GetCachedAccessible(aNode
, aWeakShell
, aAccessible
);
1430 *aFrameHint
= frame
;
1434 // Check frame to see if it is hidden
1435 if (!frame
|| !frame
->GetStyleVisibility()->IsVisible()) {
1436 *aIsHidden
= PR_TRUE
;
1443 * Attempt to create an accessible based on what we know
1445 if (content
->IsNodeOfType(nsINode::eTEXT
)) {
1446 // --- Create HTML for visible text frames ---
1447 if (frame
->IsEmpty()) {
1448 nsAutoString renderedWhitespace
;
1449 frame
->GetRenderedText(&renderedWhitespace
, nsnull
, nsnull
, 0, 1);
1450 if (renderedWhitespace
.IsEmpty()) {
1451 // Really empty -- nothing is rendered
1452 *aIsHidden
= PR_TRUE
;
1456 frame
->GetAccessible(getter_AddRefs(newAcc
));
1457 return InitAccessible(newAcc
, aAccessible
, nsnull
);
1460 PRBool isHTML
= content
->IsNodeOfType(nsINode::eHTML
);
1461 if (isHTML
&& content
->Tag() == nsAccessibilityAtoms::map
) {
1462 // Create hyper text accessible for HTML map if it is used to group links
1463 // (see http://www.w3.org/TR/WCAG10-HTML-TECHS/#group-bypass). If the HTML
1464 // map doesn't have 'name' attribute (or has empty name attribute) then we
1465 // suppose it is used for links grouping. Otherwise we think it is used in
1466 // conjuction with HTML image element and in this case we don't create any
1467 // accessible for it and don't walk into it. The accessibles for HTML area
1468 // (nsHTMLAreaAccessible) the map contains are attached as children of the
1469 // appropriate accessible for HTML image (nsHTMLImageAccessible).
1471 content
->GetAttr(kNameSpaceID_None
, nsAccessibilityAtoms::name
, name
);
1472 if (!name
.IsEmpty()) {
1473 *aIsHidden
= PR_TRUE
;
1477 nsresult rv
= CreateHyperTextAccessible(frame
, getter_AddRefs(newAcc
));
1478 NS_ENSURE_SUCCESS(rv
, rv
);
1481 nsRoleMapEntry
*roleMapEntry
= nsAccUtils::GetRoleMapEntry(aNode
);
1482 if (roleMapEntry
&& !nsCRT::strcmp(roleMapEntry
->roleString
, "presentation") &&
1483 !content
->IsFocusable()) { // For presentation only
1484 // Only create accessible for role of "presentation" if it is focusable --
1485 // in that case we need an accessible in case it gets focused, we
1486 // don't want focus ever to be 'lost'
1490 // Elements may implement nsIAccessibleProvider via XBL. This allows them to
1491 // say what kind of accessible to create.
1492 nsresult rv
= GetAccessibleByType(aNode
, getter_AddRefs(newAcc
));
1493 NS_ENSURE_SUCCESS(rv
, rv
);
1495 if (!newAcc
&& !isHTML
) {
1496 if (content
->GetNameSpaceID() == kNameSpaceID_SVG
&&
1497 content
->Tag() == nsAccessibilityAtoms::svg
) {
1498 newAcc
= new nsEnumRoleAccessible(aNode
, aWeakShell
,
1499 nsIAccessibleRole::ROLE_DIAGRAM
);
1501 else if (content
->GetNameSpaceID() == kNameSpaceID_MathML
&&
1502 content
->Tag() == nsAccessibilityAtoms::math
) {
1503 newAcc
= new nsEnumRoleAccessible(aNode
, aWeakShell
,
1504 nsIAccessibleRole::ROLE_EQUATION
);
1506 } else if (!newAcc
) { // HTML accessibles
1507 PRBool tryTagNameOrFrame
= PR_TRUE
;
1509 nsIAtom
*frameType
= frame
->GetType();
1510 if (!roleMapEntry
&&
1511 (frameType
== nsAccessibilityAtoms::tableCaptionFrame
||
1512 frameType
== nsAccessibilityAtoms::tableCellFrame
||
1513 frameType
== nsAccessibilityAtoms::tableRowGroupFrame
||
1514 frameType
== nsAccessibilityAtoms::tableRowFrame
)) {
1515 // Table-related frames don't get table-related roles
1516 // unless they are inside a table, but they may still get generic
1518 nsIContent
*tableContent
= content
;
1519 while ((tableContent
= tableContent
->GetParent()) != nsnull
) {
1520 nsIFrame
*tableFrame
= aPresShell
->GetPrimaryFrameFor(tableContent
);
1523 if (tableFrame
->GetType() == nsAccessibilityAtoms::tableOuterFrame
) {
1524 nsCOMPtr
<nsIDOMNode
> tableNode(do_QueryInterface(tableContent
));
1525 nsCOMPtr
<nsIAccessible
> tableAccessible
;
1526 GetAccessibleInShell(tableNode
, aPresShell
, getter_AddRefs(tableAccessible
));
1527 if (!tableAccessible
&& !content
->IsFocusable()) {
1529 nsRoleMapEntry
*tableRoleMapEntry
=
1530 nsAccUtils::GetRoleMapEntry(tableNode
);
1531 NS_ASSERTION(tableRoleMapEntry
&&
1532 !nsCRT::strcmp(tableRoleMapEntry
->roleString
, "presentation"),
1533 "No accessible for parent table and it didn't have role of presentation");
1535 // Table-related descendants of presentation table are also presentation
1536 // Don't create accessibles for them unless they need to fire focus events
1539 if (tableAccessible
&&
1540 nsAccUtils::Role(tableAccessible
) != nsIAccessibleRole::ROLE_TABLE
) {
1541 NS_ASSERTION(!roleMapEntry
, "Should not be changing ARIA role, just overriding impl class role");
1542 // Not in table: override role (roleMap entry was null).
1543 roleMapEntry
= &nsARIAMap::gEmptyRoleMap
;
1547 else if (tableContent
->Tag() == nsAccessibilityAtoms::table
) {
1548 // Stop before we are fooled by any additional table ancestors
1549 // This table cell frameis part of a separate ancestor table.
1550 tryTagNameOrFrame
= PR_FALSE
;
1556 tryTagNameOrFrame
= PR_FALSE
;
1559 if (tryTagNameOrFrame
) {
1560 // Prefer to use markup (mostly tag name, perhaps attributes) to
1561 // decide if and what kind of accessible to create.
1562 // The method creates accessibles for table related content too therefore
1563 // we do not call it if accessibles for table related content are
1565 rv
= CreateHTMLAccessibleByMarkup(frame
, aWeakShell
, aNode
,
1566 getter_AddRefs(newAcc
));
1567 NS_ENSURE_SUCCESS(rv
, rv
);
1570 // Do not create accessible object subtrees for non-rendered table
1571 // captions. This could not be done in
1572 // nsTableCaptionFrame::GetAccessible() because the descendants of
1573 // the table caption would still be created. By setting
1574 // *aIsHidden = PR_TRUE we ensure that no descendant accessibles are
1576 if (frame
->GetType() == nsAccessibilityAtoms::tableCaptionFrame
&&
1577 frame
->GetRect().IsEmpty()) {
1578 // XXX This is not the ideal place for this code, but right now there
1579 // is no better place:
1580 *aIsHidden
= PR_TRUE
;
1583 frame
->GetAccessible(getter_AddRefs(newAcc
)); // Try using frame to do it
1589 GetAccessibleForDeckChildren(aNode
, getter_AddRefs(newAcc
));
1592 // If no accessible, see if we need to create a generic accessible because
1593 // of some property that makes this object interesting
1594 // We don't do this for <body>, <html>, <window>, <dialog> etc. which
1595 // correspond to the doc accessible and will be created in any case
1596 if (!newAcc
&& content
->Tag() != nsAccessibilityAtoms::body
&& content
->GetParent() &&
1597 (frame
->IsFocusable() ||
1598 (isHTML
&& nsCoreUtils::HasListener(content
, NS_LITERAL_STRING("click"))) ||
1599 HasUniversalAriaProperty(content
, aWeakShell
) || roleMapEntry
||
1600 HasRelatedContent(content
) || nsCoreUtils::IsXLink(content
))) {
1601 // This content is focusable or has an interesting dynamic content accessibility property.
1602 // If it's interesting we need it in the accessibility hierarchy so that events or
1603 // other accessibles can point to it, or so that it can hold a state, etc.
1605 // Interesting HTML container which may have selectable text and/or embedded objects
1606 CreateHyperTextAccessible(frame
, getter_AddRefs(newAcc
));
1608 else { // XUL, SVG, MathML etc.
1609 // Interesting generic non-HTML container
1610 newAcc
= new nsAccessibleWrap(aNode
, aWeakShell
);
1614 return InitAccessible(newAcc
, aAccessible
, roleMapEntry
);
1618 nsAccessibilityService::HasUniversalAriaProperty(nsIContent
*aContent
,
1619 nsIWeakReference
*aWeakShell
)
1621 return aContent
->HasAttr(kNameSpaceID_None
, nsAccessibilityAtoms::aria_atomic
) ||
1622 aContent
->HasAttr(kNameSpaceID_None
, nsAccessibilityAtoms::aria_busy
) ||
1623 aContent
->HasAttr(kNameSpaceID_None
, nsAccessibilityAtoms::aria_channel
) ||
1624 aContent
->HasAttr(kNameSpaceID_None
, nsAccessibilityAtoms::aria_controls
) ||
1625 aContent
->HasAttr(kNameSpaceID_None
, nsAccessibilityAtoms::aria_datatype
) ||
1626 aContent
->HasAttr(kNameSpaceID_None
, nsAccessibilityAtoms::aria_describedby
) ||
1627 aContent
->HasAttr(kNameSpaceID_None
, nsAccessibilityAtoms::aria_dropeffect
) ||
1628 aContent
->HasAttr(kNameSpaceID_None
, nsAccessibilityAtoms::aria_flowto
) ||
1629 aContent
->HasAttr(kNameSpaceID_None
, nsAccessibilityAtoms::aria_grab
) ||
1630 aContent
->HasAttr(kNameSpaceID_None
, nsAccessibilityAtoms::aria_haspopup
) ||
1631 aContent
->HasAttr(kNameSpaceID_None
, nsAccessibilityAtoms::aria_invalid
) ||
1632 aContent
->HasAttr(kNameSpaceID_None
, nsAccessibilityAtoms::aria_label
) ||
1633 aContent
->HasAttr(kNameSpaceID_None
, nsAccessibilityAtoms::aria_labelledby
) ||
1634 aContent
->HasAttr(kNameSpaceID_None
, nsAccessibilityAtoms::aria_live
) ||
1635 aContent
->HasAttr(kNameSpaceID_None
, nsAccessibilityAtoms::aria_owns
) ||
1636 aContent
->HasAttr(kNameSpaceID_None
, nsAccessibilityAtoms::aria_relevant
) ||
1637 aContent
->HasAttr(kNameSpaceID_None
, nsAccessibilityAtoms::aria_required
) ||
1638 aContent
->HasAttr(kNameSpaceID_None
, nsAccessibilityAtoms::aria_sort
);
1642 nsAccessibilityService::GetRelevantContentNodeFor(nsIDOMNode
*aNode
,
1643 nsIDOMNode
**aRelevantNode
)
1645 // The method returns node that is relevant for attached accessible check.
1646 // Sometimes element that is XBL widget hasn't accessible children in
1647 // anonymous content. This method check whether given node can be accessible
1648 // by looking through all nested bindings that given node is anonymous for. If
1649 // there is XBL widget that deniedes to be accessible for given node then the
1650 // method returns that XBL widget otherwise it returns given node.
1652 // For example, the algorithm allows us to handle following cases:
1653 // 1. xul:dialog element has buttons (like 'ok' and 'cancel') in anonymous
1654 // content. When node is dialog's button then we dialog's button since button
1655 // of xul:dialog is accessible anonymous node.
1656 // 2. xul:texbox has html:input in anonymous content. When given node is
1657 // html:input elmement then we return xul:textbox since xul:textbox doesn't
1658 // allow accessible nodes in anonymous content.
1659 // 3. xforms:input that is hosted in xul document contains xul:textbox
1660 // element. When given node is html:input or xul:textbox then we return
1661 // xforms:input element since xforms:input hasn't accessible anonymous
1664 NS_ENSURE_ARG(aNode
);
1665 NS_ENSURE_ARG_POINTER(aRelevantNode
);
1668 nsCOMPtr
<nsIContent
> content(do_QueryInterface(aNode
));
1670 // Build stack of binding parents so we can walk it in reverse.
1671 nsIContent
*bindingParent
;
1672 nsCOMArray
<nsIContent
> bindingsStack
;
1674 for (bindingParent
= content
->GetBindingParent(); bindingParent
!= nsnull
&&
1675 bindingParent
!= bindingParent
->GetBindingParent();
1676 bindingParent
= bindingParent
->GetBindingParent()) {
1677 bindingsStack
.AppendObject(bindingParent
);
1680 PRInt32 bindingsCount
= bindingsStack
.Count();
1681 for (PRInt32 index
= bindingsCount
- 1; index
>= 0 ; index
--) {
1682 bindingParent
= bindingsStack
[index
];
1683 nsCOMPtr
<nsIDOMNode
> bindingNode(do_QueryInterface(bindingParent
));
1685 // Try to get an accessible by type since XBL widget can be accessible
1686 // only if it implements nsIAccessibleProvider interface.
1687 nsCOMPtr
<nsIAccessible
> accessible
;
1688 rv
= GetAccessibleByType(bindingNode
, getter_AddRefs(accessible
));
1690 if (NS_SUCCEEDED(rv
)) {
1691 nsCOMPtr
<nsPIAccessible
> paccessible(do_QueryInterface(accessible
));
1693 PRBool allowsAnonChildren
= PR_FALSE
;
1694 paccessible
->GetAllowsAnonChildAccessibles(&allowsAnonChildren
);
1695 if (!allowsAnonChildren
) {
1696 NS_ADDREF(*aRelevantNode
= bindingNode
);
1705 NS_ADDREF(*aRelevantNode
= aNode
);
1709 nsresult
nsAccessibilityService::GetAccessibleByType(nsIDOMNode
*aNode
,
1710 nsIAccessible
**aAccessible
)
1712 NS_ENSURE_ARG(aNode
);
1713 NS_ENSURE_ARG_POINTER(aAccessible
);
1715 *aAccessible
= nsnull
;
1717 nsCOMPtr
<nsIAccessibleProvider
> accessibleProvider(do_QueryInterface(aNode
));
1718 if (!accessibleProvider
)
1722 nsresult rv
= accessibleProvider
->GetAccessibleType(&type
);
1723 NS_ENSURE_SUCCESS(rv
, rv
);
1725 if (type
== nsIAccessibleProvider::OuterDoc
)
1726 return CreateOuterDocAccessible(aNode
, aAccessible
);
1728 nsCOMPtr
<nsIWeakReference
> weakShell
;
1729 GetShellFromNode(aNode
, getter_AddRefs(weakShell
));
1734 case nsIAccessibleProvider::NoAccessible
:
1737 case nsIAccessibleProvider::XULAlert
:
1738 *aAccessible
= new nsXULAlertAccessible(aNode
, weakShell
);
1740 case nsIAccessibleProvider::XULButton
:
1741 *aAccessible
= new nsXULButtonAccessible(aNode
, weakShell
);
1743 case nsIAccessibleProvider::XULCheckbox
:
1744 *aAccessible
= new nsXULCheckboxAccessible(aNode
, weakShell
);
1746 case nsIAccessibleProvider::XULColorPicker
:
1747 *aAccessible
= new nsXULColorPickerAccessible(aNode
, weakShell
);
1749 case nsIAccessibleProvider::XULColorPickerTile
:
1750 *aAccessible
= new nsXULColorPickerTileAccessible(aNode
, weakShell
);
1752 case nsIAccessibleProvider::XULCombobox
:
1753 *aAccessible
= new nsXULComboboxAccessible(aNode
, weakShell
);
1755 case nsIAccessibleProvider::XULDropmarker
:
1756 *aAccessible
= new nsXULDropmarkerAccessible(aNode
, weakShell
);
1758 case nsIAccessibleProvider::XULGroupbox
:
1759 *aAccessible
= new nsXULGroupboxAccessible(aNode
, weakShell
);
1761 case nsIAccessibleProvider::XULImage
:
1763 // Don't include nameless images in accessible tree
1764 nsCOMPtr
<nsIDOMElement
> elt(do_QueryInterface(aNode
));
1766 return NS_ERROR_FAILURE
;
1768 PRBool hasTextEquivalent
;
1769 // Prefer value over tooltiptext
1770 elt
->HasAttribute(NS_LITERAL_STRING("tooltiptext"), &hasTextEquivalent
);
1771 if (!hasTextEquivalent
)
1774 *aAccessible
= new nsHTMLImageAccessibleWrap(aNode
, weakShell
);
1777 case nsIAccessibleProvider::XULLink
:
1778 *aAccessible
= new nsXULLinkAccessible(aNode
, weakShell
);
1780 case nsIAccessibleProvider::XULListbox
:
1781 *aAccessible
= new nsXULListboxAccessible(aNode
, weakShell
);
1783 case nsIAccessibleProvider::XULListCell
:
1784 *aAccessible
= new nsXULListCellAccessible(aNode
, weakShell
);
1786 case nsIAccessibleProvider::XULListHead
:
1787 *aAccessible
= new nsXULColumnsAccessible(aNode
, weakShell
);
1789 case nsIAccessibleProvider::XULListHeader
:
1790 *aAccessible
= new nsXULColumnItemAccessible(aNode
, weakShell
);
1792 case nsIAccessibleProvider::XULListitem
:
1793 *aAccessible
= new nsXULListitemAccessible(aNode
, weakShell
);
1795 case nsIAccessibleProvider::XULMenubar
:
1796 *aAccessible
= new nsXULMenubarAccessible(aNode
, weakShell
);
1798 case nsIAccessibleProvider::XULMenuitem
:
1799 *aAccessible
= new nsXULMenuitemAccessibleWrap(aNode
, weakShell
);
1801 case nsIAccessibleProvider::XULMenupopup
:
1803 #ifdef MOZ_ACCESSIBILITY_ATK
1804 // ATK considers this node to be redundant when within menubars, and it makes menu
1805 // navigation with assistive technologies more difficult
1806 // XXX In the future we will should this for consistency across the nsIAccessible
1807 // implementations on each platform for a consistent scripting environment, but
1808 // then strip out redundant accessibles in the nsAccessibleWrap class for each platform.
1809 nsCOMPtr
<nsIContent
> content
= do_QueryInterface(aNode
);
1811 nsIContent
*parent
= content
->GetParent();
1812 if (parent
&& parent
->NodeInfo()->Equals(nsAccessibilityAtoms::menu
, kNameSpaceID_XUL
)) {
1817 *aAccessible
= new nsXULMenupopupAccessible(aNode
, weakShell
);
1820 case nsIAccessibleProvider::XULMenuSeparator
:
1821 *aAccessible
= new nsXULMenuSeparatorAccessible(aNode
, weakShell
);
1823 case nsIAccessibleProvider::XULPane
:
1824 *aAccessible
= new nsEnumRoleAccessible(aNode
, weakShell
, nsIAccessibleRole::ROLE_PANE
);
1826 case nsIAccessibleProvider::XULProgressMeter
:
1827 *aAccessible
= new nsXULProgressMeterAccessible(aNode
, weakShell
);
1829 case nsIAccessibleProvider::XULStatusBar
:
1830 *aAccessible
= new nsXULStatusBarAccessible(aNode
, weakShell
);
1832 case nsIAccessibleProvider::XULScale
:
1833 *aAccessible
= new nsXULSliderAccessible(aNode
, weakShell
);
1835 case nsIAccessibleProvider::XULRadioButton
:
1836 *aAccessible
= new nsXULRadioButtonAccessible(aNode
, weakShell
);
1838 case nsIAccessibleProvider::XULRadioGroup
:
1839 *aAccessible
= new nsXULRadioGroupAccessible(aNode
, weakShell
);
1841 case nsIAccessibleProvider::XULTab
:
1842 *aAccessible
= new nsXULTabAccessible(aNode
, weakShell
);
1844 case nsIAccessibleProvider::XULTabBox
:
1845 *aAccessible
= new nsXULTabBoxAccessible(aNode
, weakShell
);
1847 case nsIAccessibleProvider::XULTabs
:
1848 *aAccessible
= new nsXULTabsAccessible(aNode
, weakShell
);
1850 case nsIAccessibleProvider::XULText
:
1851 *aAccessible
= new nsXULTextAccessible(aNode
, weakShell
);
1853 case nsIAccessibleProvider::XULTextBox
:
1854 *aAccessible
= new nsXULTextFieldAccessible(aNode
, weakShell
);
1856 case nsIAccessibleProvider::XULThumb
:
1857 *aAccessible
= new nsXULThumbAccessible(aNode
, weakShell
);
1859 case nsIAccessibleProvider::XULTree
:
1860 *aAccessible
= new nsXULTreeAccessibleWrap(aNode
, weakShell
);
1862 case nsIAccessibleProvider::XULTreeColumns
:
1863 *aAccessible
= new nsXULTreeColumnsAccessibleWrap(aNode
, weakShell
);
1865 case nsIAccessibleProvider::XULTreeColumnItem
:
1866 *aAccessible
= new nsXULColumnItemAccessible(aNode
, weakShell
);
1868 case nsIAccessibleProvider::XULToolbar
:
1869 *aAccessible
= new nsXULToolbarAccessible(aNode
, weakShell
);
1871 case nsIAccessibleProvider::XULToolbarSeparator
:
1872 *aAccessible
= new nsXULToolbarSeparatorAccessible(aNode
, weakShell
);
1874 case nsIAccessibleProvider::XULTooltip
:
1875 *aAccessible
= new nsXULTooltipAccessible(aNode
, weakShell
);
1877 case nsIAccessibleProvider::XULToolbarButton
:
1878 *aAccessible
= new nsXULToolbarButtonAccessible(aNode
, weakShell
);
1882 #ifndef DISABLE_XFORMS_HOOKS
1884 case nsIAccessibleProvider::XFormsContainer
:
1885 *aAccessible
= new nsXFormsContainerAccessible(aNode
, weakShell
);
1888 case nsIAccessibleProvider::XFormsLabel
:
1889 *aAccessible
= new nsXFormsLabelAccessible(aNode
, weakShell
);
1891 case nsIAccessibleProvider::XFormsOuput
:
1892 *aAccessible
= new nsXFormsOutputAccessible(aNode
, weakShell
);
1894 case nsIAccessibleProvider::XFormsTrigger
:
1895 *aAccessible
= new nsXFormsTriggerAccessible(aNode
, weakShell
);
1897 case nsIAccessibleProvider::XFormsInput
:
1898 *aAccessible
= new nsXFormsInputAccessible(aNode
, weakShell
);
1900 case nsIAccessibleProvider::XFormsInputBoolean
:
1901 *aAccessible
= new nsXFormsInputBooleanAccessible(aNode
, weakShell
);
1903 case nsIAccessibleProvider::XFormsInputDate
:
1904 *aAccessible
= new nsXFormsInputDateAccessible(aNode
, weakShell
);
1906 case nsIAccessibleProvider::XFormsSecret
:
1907 *aAccessible
= new nsXFormsSecretAccessible(aNode
, weakShell
);
1909 case nsIAccessibleProvider::XFormsSliderRange
:
1910 *aAccessible
= new nsXFormsRangeAccessible(aNode
, weakShell
);
1912 case nsIAccessibleProvider::XFormsSelect
:
1913 *aAccessible
= new nsXFormsSelectAccessible(aNode
, weakShell
);
1915 case nsIAccessibleProvider::XFormsChoices
:
1916 *aAccessible
= new nsXFormsChoicesAccessible(aNode
, weakShell
);
1918 case nsIAccessibleProvider::XFormsSelectFull
:
1919 *aAccessible
= new nsXFormsSelectFullAccessible(aNode
, weakShell
);
1921 case nsIAccessibleProvider::XFormsItemCheckgroup
:
1922 *aAccessible
= new nsXFormsItemCheckgroupAccessible(aNode
, weakShell
);
1924 case nsIAccessibleProvider::XFormsItemRadiogroup
:
1925 *aAccessible
= new nsXFormsItemRadiogroupAccessible(aNode
, weakShell
);
1927 case nsIAccessibleProvider::XFormsSelectCombobox
:
1928 *aAccessible
= new nsXFormsSelectComboboxAccessible(aNode
, weakShell
);
1930 case nsIAccessibleProvider::XFormsItemCombobox
:
1931 *aAccessible
= new nsXFormsItemComboboxAccessible(aNode
, weakShell
);
1934 case nsIAccessibleProvider::XFormsDropmarkerWidget
:
1935 *aAccessible
= new nsXFormsDropmarkerWidgetAccessible(aNode
, weakShell
);
1937 case nsIAccessibleProvider::XFormsCalendarWidget
:
1938 *aAccessible
= new nsXFormsCalendarWidgetAccessible(aNode
, weakShell
);
1940 case nsIAccessibleProvider::XFormsComboboxPopupWidget
:
1941 *aAccessible
= new nsXFormsComboboxPopupWidgetAccessible(aNode
, weakShell
);
1946 return NS_ERROR_FAILURE
;
1950 return NS_ERROR_OUT_OF_MEMORY
;
1952 NS_ADDREF(*aAccessible
);
1956 NS_IMETHODIMP
nsAccessibilityService::AddNativeRootAccessible(void * aAtkAccessible
, nsIAccessible
**aRootAccessible
)
1958 #ifdef MOZ_ACCESSIBILITY_ATK
1959 nsNativeRootAccessibleWrap
* rootAccWrap
=
1960 new nsNativeRootAccessibleWrap((AtkObject
*)aAtkAccessible
);
1962 *aRootAccessible
= static_cast<nsIAccessible
*>(rootAccWrap
);
1963 NS_ADDREF(*aRootAccessible
);
1965 nsRefPtr
<nsApplicationAccessibleWrap
> appRoot
=
1966 nsAccessNode::GetApplicationAccessible();
1967 NS_ENSURE_STATE(appRoot
);
1969 appRoot
->AddRootAccessible(*aRootAccessible
);
1973 return NS_ERROR_NOT_IMPLEMENTED
;
1977 NS_IMETHODIMP
nsAccessibilityService::RemoveNativeRootAccessible(nsIAccessible
* aRootAccessible
)
1979 #ifdef MOZ_ACCESSIBILITY_ATK
1980 void* atkAccessible
;
1981 aRootAccessible
->GetNativeInterface(&atkAccessible
);
1983 nsRefPtr
<nsApplicationAccessibleWrap
> appRoot
=
1984 nsAccessNode::GetApplicationAccessible();
1985 NS_ENSURE_STATE(appRoot
);
1987 appRoot
->RemoveRootAccessible(aRootAccessible
);
1991 return NS_ERROR_NOT_IMPLEMENTED
;
1995 // Called from layout when the frame tree owned by a node changes significantly
1996 NS_IMETHODIMP
nsAccessibilityService::InvalidateSubtreeFor(nsIPresShell
*aShell
,
1997 nsIContent
*aChangeContent
,
2000 NS_ASSERTION(aEvent
== nsIAccessibleEvent::EVENT_ASYNCH_SIGNIFICANT_CHANGE
||
2001 aEvent
== nsIAccessibleEvent::EVENT_ASYNCH_SHOW
||
2002 aEvent
== nsIAccessibleEvent::EVENT_ASYNCH_HIDE
||
2003 aEvent
== nsIAccessibleEvent::EVENT_DOM_SIGNIFICANT_CHANGE
||
2004 aEvent
== nsIAccessibleEvent::EVENT_DOM_CREATE
||
2005 aEvent
== nsIAccessibleEvent::EVENT_DOM_DESTROY
,
2006 "Incorrect aEvent passed in");
2008 NS_ENSURE_ARG_POINTER(aShell
);
2009 nsCOMPtr
<nsIAccessibleDocument
> accessibleDoc
=
2010 nsAccessNode::GetDocAccessibleFor(aShell
->GetDocument());
2011 nsCOMPtr
<nsPIAccessibleDocument
> privateAccessibleDoc
=
2012 do_QueryInterface(accessibleDoc
);
2013 if (!privateAccessibleDoc
) {
2016 return privateAccessibleDoc
->InvalidateCacheSubtree(aChangeContent
, aEvent
);
2019 //////////////////////////////////////////////////////////////////////
2020 //////////////////////////////////////////////////////////////////////
2023 nsAccessibilityService::GetAccessibilityService(nsIAccessibilityService
** aResult
)
2025 NS_PRECONDITION(aResult
!= nsnull
, "null ptr");
2027 return NS_ERROR_NULL_POINTER
;
2030 if (!nsAccessibilityService::gAccessibilityService
) {
2031 gAccessibilityService
= new nsAccessibilityService();
2032 if (!gAccessibilityService
) {
2033 return NS_ERROR_OUT_OF_MEMORY
;
2036 *aResult
= nsAccessibilityService::gAccessibilityService
;
2037 NS_ADDREF(*aResult
);
2042 NS_GetAccessibilityService(nsIAccessibilityService
** aResult
)
2044 return nsAccessibilityService::GetAccessibilityService(aResult
);
2048 nsAccessibilityService::GetAccessibleForDeckChildren(nsIDOMNode
*aNode
, nsIAccessible
** aAccessible
)
2050 nsCOMPtr
<nsIWeakReference
> weakShell
;
2051 GetShellFromNode(aNode
, getter_AddRefs(weakShell
));
2052 NS_ENSURE_TRUE(weakShell
, NS_ERROR_FAILURE
);
2053 nsCOMPtr
<nsIPresShell
> shell(do_QueryReferent(weakShell
));
2054 NS_ENSURE_TRUE(shell
, NS_ERROR_FAILURE
);
2056 nsIFrame
* frame
= nsnull
;
2057 nsIFrame
* parentFrame
= nsnull
;
2058 nsCOMPtr
<nsIContent
> content(do_QueryInterface(aNode
));
2061 frame
= shell
->GetPrimaryFrameFor(content
);
2064 if (frame
&& (frame
->GetType() == nsAccessibilityAtoms::boxFrame
||
2065 frame
->GetType() == nsAccessibilityAtoms::scrollFrame
)) {
2066 parentFrame
= frame
->GetParent();
2067 if (parentFrame
&& parentFrame
->GetType() == nsAccessibilityAtoms::deckFrame
) {
2068 // If deck frame is for xul:tabpanels element then the given node has
2069 // tabpanel accessible.
2070 nsCOMPtr
<nsIContent
> parentContent
= parentFrame
->GetContent();
2072 if (parentContent
->NodeInfo()->Equals(nsAccessibilityAtoms::tabpanels
,
2073 kNameSpaceID_XUL
)) {
2074 *aAccessible
= new nsXULTabpanelAccessible(aNode
, weakShell
);
2078 new nsEnumRoleAccessible(aNode
, weakShell
,
2079 nsIAccessibleRole::ROLE_PROPERTYPAGE
);
2081 NS_ENSURE_TRUE(*aAccessible
, NS_ERROR_OUT_OF_MEMORY
);
2083 NS_ADDREF(*aAccessible
);