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) 2003
20 * the Initial Developer. All Rights Reserved.
23 * Original Author: Aaron Leventhal (aaronl@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 #include "nsAccessNodeWrap.h"
41 #include "AccessibleApplication.h"
42 #include "ISimpleDOMNode_i.c"
44 #include "nsAccessibilityAtoms.h"
45 #include "nsAccessibilityService.h"
46 #include "nsApplicationAccessibleWrap.h"
47 #include "nsCoreUtils.h"
48 #include "nsRootAccessible.h"
50 #include "nsAttrName.h"
51 #include "nsIDocument.h"
52 #include "nsIDOMNodeList.h"
53 #include "nsIDOMNSHTMLElement.h"
54 #include "nsIDOMViewCSS.h"
56 #include "nsINameSpaceManager.h"
57 #include "nsIPrefService.h"
58 #include "nsIPrefBranch.h"
59 #include "nsPIDOMWindow.h"
60 #include "nsIServiceManager.h"
62 /// the accessible library and cached methods
63 HINSTANCE
nsAccessNodeWrap::gmAccLib
= nsnull
;
64 HINSTANCE
nsAccessNodeWrap::gmUserLib
= nsnull
;
65 LPFNACCESSIBLEOBJECTFROMWINDOW
nsAccessNodeWrap::gmAccessibleObjectFromWindow
= nsnull
;
66 LPFNNOTIFYWINEVENT
nsAccessNodeWrap::gmNotifyWinEvent
= nsnull
;
67 LPFNGETGUITHREADINFO
nsAccessNodeWrap::gmGetGUIThreadInfo
= nsnull
;
69 PRBool
nsAccessNodeWrap::gIsEnumVariantSupportDisabled
= 0;
70 // Used to determine whether an IAccessible2 compatible screen reader is loaded.
71 PRBool
nsAccessNodeWrap::gIsIA2Disabled
= PR_FALSE
;
73 AccTextChangeEvent
* nsAccessNodeWrap::gTextEvent
= nsnull
;
75 // Pref to disallow CtrlTab preview functionality if JAWS or Window-Eyes are
77 #define CTRLTAB_DISALLOW_FOR_SCREEN_READERS_PREF "browser.ctrlTab.disallowForScreenReaders"
80 /* For documentation of the accessibility architecture,
81 * see http://lxr.mozilla.org/seamonkey/source/accessible/accessible-docs.html
84 ////////////////////////////////////////////////////////////////////////////////
86 ////////////////////////////////////////////////////////////////////////////////
89 nsAccessNodeWrap(nsIContent
*aContent
, nsIWeakReference
*aShell
) :
90 nsAccessNode(aContent
, aShell
)
94 nsAccessNodeWrap::~nsAccessNodeWrap()
98 //-----------------------------------------------------
99 // nsISupports methods
100 //-----------------------------------------------------
102 NS_IMPL_ISUPPORTS_INHERITED1(nsAccessNodeWrap
, nsAccessNode
, nsIWinAccessNode
);
104 //-----------------------------------------------------
105 // nsIWinAccessNode methods
106 //-----------------------------------------------------
109 nsAccessNodeWrap::QueryNativeInterface(REFIID aIID
, void** aInstancePtr
)
111 return QueryInterface(aIID
, aInstancePtr
);
114 //-----------------------------------------------------
115 // IUnknown interface methods - see iunknown.h for documentation
116 //-----------------------------------------------------
118 STDMETHODIMP
nsAccessNodeWrap::QueryInterface(REFIID iid
, void** ppv
)
122 if (IID_IUnknown
== iid
|| IID_ISimpleDOMNode
== iid
)
123 *ppv
= static_cast<ISimpleDOMNode
*>(this);
126 return E_NOINTERFACE
; //iid not supported.
128 (reinterpret_cast<IUnknown
*>(*ppv
))->AddRef();
133 nsAccessNodeWrap::QueryService(REFGUID guidService
, REFIID iid
, void** ppv
)
135 static const GUID IID_SimpleDOMDeprecated
= {0x0c539790,0x12e4,0x11cf,0xb6,0x61,0x00,0xaa,0x00,0x4c,0xd6,0xd8};
136 if (guidService
!= IID_ISimpleDOMNode
&&
137 guidService
!= IID_SimpleDOMDeprecated
&&
138 guidService
!= IID_IAccessible
&& guidService
!= IID_IAccessible2
&&
139 guidService
!= IID_IAccessibleApplication
)
142 // Can get to IAccessibleApplication from any node via QS
143 if (iid
== IID_IAccessibleApplication
) {
144 nsApplicationAccessible
*applicationAcc
= GetApplicationAccessible();
146 return E_NOINTERFACE
;
148 nsresult rv
= applicationAcc
->QueryNativeInterface(iid
, ppv
);
149 return NS_SUCCEEDED(rv
) ? S_OK
: E_NOINTERFACE
;
153 * To get an ISimpleDOMNode, ISimpleDOMDocument, ISimpleDOMText
154 * or any IAccessible2 interface on should use IServiceProvider like this:
155 * -----------------------------------------------------------------------
156 * ISimpleDOMDocument *pAccDoc = NULL;
157 * IServiceProvider *pServProv = NULL;
158 * pAcc->QueryInterface(IID_IServiceProvider, (void**)&pServProv);
161 * pServProv->QueryService(unused, IID_ISimpleDOMDocument, (void**)&pAccDoc);
162 * pServProv->Release();
166 return QueryInterface(iid
, ppv
);
169 //-----------------------------------------------------
170 // ISimpleDOMNode methods
171 //-----------------------------------------------------
173 STDMETHODIMP
nsAccessNodeWrap::get_nodeInfo(
174 /* [out] */ BSTR __RPC_FAR
*aNodeName
,
175 /* [out] */ short __RPC_FAR
*aNameSpaceID
,
176 /* [out] */ BSTR __RPC_FAR
*aNodeValue
,
177 /* [out] */ unsigned int __RPC_FAR
*aNumChildren
,
178 /* [out] */ unsigned int __RPC_FAR
*aUniqueID
,
179 /* [out] */ unsigned short __RPC_FAR
*aNodeType
)
183 *aNodeValue
= nsnull
;
188 nsCOMPtr
<nsIDOMNode
> DOMNode(do_QueryInterface(GetNode()));
190 PRUint16 nodeType
= 0;
191 DOMNode
->GetNodeType(&nodeType
);
192 *aNodeType
=static_cast<unsigned short>(nodeType
);
194 if (*aNodeType
!= NODETYPE_TEXT
) {
195 nsAutoString nodeName
;
196 DOMNode
->GetNodeName(nodeName
);
197 *aNodeName
= ::SysAllocString(nodeName
.get());
200 nsAutoString nodeValue
;
202 DOMNode
->GetNodeValue(nodeValue
);
203 *aNodeValue
= ::SysAllocString(nodeValue
.get());
205 *aNameSpaceID
= IsContent() ?
206 static_cast<short>(mContent
->GetNameSpaceID()) : 0;
208 // This is a unique ID for every content node. The 3rd party
209 // accessibility application can compare this to the childID we
210 // return for events such as focus events, to correlate back to
211 // data nodes in their internal object model.
213 GetUniqueID(&uniqueID
);
214 *aUniqueID
= - NS_PTR_TO_INT32(uniqueID
);
216 *aNumChildren
= GetNode()->GetChildCount();
218 } __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
224 STDMETHODIMP
nsAccessNodeWrap::get_attributes(
225 /* [in] */ unsigned short aMaxAttribs
,
226 /* [length_is][size_is][out] */ BSTR __RPC_FAR
*aAttribNames
,
227 /* [length_is][size_is][out] */ short __RPC_FAR
*aNameSpaceIDs
,
228 /* [length_is][size_is][out] */ BSTR __RPC_FAR
*aAttribValues
,
229 /* [out] */ unsigned short __RPC_FAR
*aNumAttribs
)
234 if (IsDefunct() || IsDocument())
237 PRUint32 numAttribs
= mContent
->GetAttrCount();
238 if (numAttribs
> aMaxAttribs
)
239 numAttribs
= aMaxAttribs
;
240 *aNumAttribs
= static_cast<unsigned short>(numAttribs
);
242 for (PRUint32 index
= 0; index
< numAttribs
; index
++) {
243 aNameSpaceIDs
[index
] = 0; aAttribValues
[index
] = aAttribNames
[index
] = nsnull
;
244 nsAutoString attributeValue
;
246 const nsAttrName
* name
= mContent
->GetAttrNameAt(index
);
247 aNameSpaceIDs
[index
] = static_cast<short>(name
->NamespaceID());
248 aAttribNames
[index
] = ::SysAllocString(name
->LocalName()->GetUTF16String());
249 mContent
->GetAttr(name
->NamespaceID(), name
->LocalName(), attributeValue
);
250 aAttribValues
[index
] = ::SysAllocString(attributeValue
.get());
252 } __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
258 STDMETHODIMP
nsAccessNodeWrap::get_attributesForNames(
259 /* [in] */ unsigned short aNumAttribs
,
260 /* [length_is][size_is][in] */ BSTR __RPC_FAR
*aAttribNames
,
261 /* [length_is][size_is][in] */ short __RPC_FAR
*aNameSpaceID
,
262 /* [length_is][size_is][retval] */ BSTR __RPC_FAR
*aAttribValues
)
265 if (IsDefunct() || IsDocument())
268 nsCOMPtr
<nsIDOMElement
> domElement(do_QueryInterface(mContent
));
269 nsCOMPtr
<nsINameSpaceManager
> nameSpaceManager
=
270 do_GetService(NS_NAMESPACEMANAGER_CONTRACTID
);
274 for (index
= 0; index
< aNumAttribs
; index
++) {
275 aAttribValues
[index
] = nsnull
;
276 if (aAttribNames
[index
]) {
277 nsAutoString attributeValue
, nameSpaceURI
;
278 nsAutoString
attributeName(nsDependentString(static_cast<PRUnichar
*>(aAttribNames
[index
])));
281 if (aNameSpaceID
[index
]>0 &&
282 NS_SUCCEEDED(nameSpaceManager
->GetNameSpaceURI(aNameSpaceID
[index
], nameSpaceURI
)))
283 rv
= domElement
->GetAttributeNS(nameSpaceURI
, attributeName
, attributeValue
);
285 rv
= domElement
->GetAttribute(attributeName
, attributeValue
);
287 if (NS_SUCCEEDED(rv
))
288 aAttribValues
[index
] = ::SysAllocString(attributeValue
.get());
291 } __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
296 /* To do: use media type if not null */
297 STDMETHODIMP
nsAccessNodeWrap::get_computedStyle(
298 /* [in] */ unsigned short aMaxStyleProperties
,
299 /* [in] */ boolean aUseAlternateView
,
300 /* [length_is][size_is][out] */ BSTR __RPC_FAR
*aStyleProperties
,
301 /* [length_is][size_is][out] */ BSTR __RPC_FAR
*aStyleValues
,
302 /* [out] */ unsigned short __RPC_FAR
*aNumStyleProperties
)
305 *aNumStyleProperties
= 0;
307 if (IsDefunct() || IsDocument())
310 nsCOMPtr
<nsIDOMCSSStyleDeclaration
> cssDecl
=
311 nsCoreUtils::GetComputedStyleDeclaration(EmptyString(), mContent
);
312 NS_ENSURE_TRUE(cssDecl
, E_FAIL
);
315 cssDecl
->GetLength(&length
);
317 PRUint32 index
, realIndex
;
318 for (index
= realIndex
= 0; index
< length
&& realIndex
< aMaxStyleProperties
; index
++) {
319 nsAutoString property
, value
;
320 if (NS_SUCCEEDED(cssDecl
->Item(index
, property
)) && property
.CharAt(0) != '-') // Ignore -moz-* properties
321 cssDecl
->GetPropertyValue(property
, value
); // Get property value
322 if (!value
.IsEmpty()) {
323 aStyleProperties
[realIndex
] = ::SysAllocString(property
.get());
324 aStyleValues
[realIndex
] = ::SysAllocString(value
.get());
328 *aNumStyleProperties
= static_cast<unsigned short>(realIndex
);
329 } __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
335 STDMETHODIMP
nsAccessNodeWrap::get_computedStyleForProperties(
336 /* [in] */ unsigned short aNumStyleProperties
,
337 /* [in] */ boolean aUseAlternateView
,
338 /* [length_is][size_is][in] */ BSTR __RPC_FAR
*aStyleProperties
,
339 /* [length_is][size_is][out] */ BSTR __RPC_FAR
*aStyleValues
)
342 if (IsDefunct() || IsDocument())
345 nsCOMPtr
<nsIDOMCSSStyleDeclaration
> cssDecl
=
346 nsCoreUtils::GetComputedStyleDeclaration(EmptyString(), mContent
);
347 NS_ENSURE_TRUE(cssDecl
, E_FAIL
);
350 for (index
= 0; index
< aNumStyleProperties
; index
++) {
352 if (aStyleProperties
[index
])
353 cssDecl
->GetPropertyValue(nsDependentString(static_cast<PRUnichar
*>(aStyleProperties
[index
])), value
); // Get property value
354 aStyleValues
[index
] = ::SysAllocString(value
.get());
356 } __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
361 STDMETHODIMP
nsAccessNodeWrap::scrollTo(/* [in] */ boolean aScrollTopLeft
)
364 PRUint32 scrollType
=
365 aScrollTopLeft
? nsIAccessibleScrollType::SCROLL_TYPE_TOP_LEFT
:
366 nsIAccessibleScrollType::SCROLL_TYPE_BOTTOM_RIGHT
;
368 nsresult rv
= ScrollTo(scrollType
);
369 if (NS_SUCCEEDED(rv
))
371 } __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
377 nsAccessNodeWrap::MakeAccessNode(nsINode
*aNode
)
382 nsAccessNodeWrap
*newNode
= NULL
;
384 ISimpleDOMNode
*iNode
= NULL
;
386 GetAccService()->GetAccessibleInWeakShell(aNode
, mWeakShell
);
388 IAccessible
*msaaAccessible
= nsnull
;
389 acc
->GetNativeInterface((void**)&msaaAccessible
); // addrefs
390 msaaAccessible
->QueryInterface(IID_ISimpleDOMNode
, (void**)&iNode
); // addrefs
391 msaaAccessible
->Release(); // Release IAccessible
394 nsCOMPtr
<nsIContent
> content(do_QueryInterface(aNode
));
396 NS_NOTREACHED("The node is a document which is not accessible!");
400 newNode
= new nsAccessNodeWrap(content
, mWeakShell
);
405 iNode
= static_cast<ISimpleDOMNode
*>(newNode
);
413 STDMETHODIMP
nsAccessNodeWrap::get_parentNode(ISimpleDOMNode __RPC_FAR
*__RPC_FAR
*aNode
)
419 *aNode
= MakeAccessNode(GetNode()->GetNodeParent());
421 } __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
426 STDMETHODIMP
nsAccessNodeWrap::get_firstChild(ISimpleDOMNode __RPC_FAR
*__RPC_FAR
*aNode
)
432 *aNode
= MakeAccessNode(GetNode()->GetFirstChild());
434 } __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
439 STDMETHODIMP
nsAccessNodeWrap::get_lastChild(ISimpleDOMNode __RPC_FAR
*__RPC_FAR
*aNode
)
445 *aNode
= MakeAccessNode(GetNode()->GetLastChild());
447 } __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
452 STDMETHODIMP
nsAccessNodeWrap::get_previousSibling(ISimpleDOMNode __RPC_FAR
*__RPC_FAR
*aNode
)
458 *aNode
= MakeAccessNode(GetNode()->GetPreviousSibling());
460 } __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
465 STDMETHODIMP
nsAccessNodeWrap::get_nextSibling(ISimpleDOMNode __RPC_FAR
*__RPC_FAR
*aNode
)
471 *aNode
= MakeAccessNode(GetNode()->GetNextSibling());
473 } __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
479 nsAccessNodeWrap::get_childAt(unsigned aChildIndex
,
480 ISimpleDOMNode __RPC_FAR
*__RPC_FAR
*aNode
)
488 *aNode
= MakeAccessNode(GetNode()->GetChildAt(aChildIndex
));
490 } __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
496 nsAccessNodeWrap::get_innerHTML(BSTR __RPC_FAR
*aInnerHTML
)
499 *aInnerHTML
= nsnull
;
501 nsCOMPtr
<nsIDOMNSHTMLElement
> domNSElement(do_QueryInterface(GetNode()));
503 return E_FAIL
; // Node already shut down
505 nsAutoString innerHTML
;
506 domNSElement
->GetInnerHTML(innerHTML
);
507 if (innerHTML
.IsEmpty())
510 *aInnerHTML
= ::SysAllocStringLen(innerHTML
.get(), innerHTML
.Length());
512 return E_OUTOFMEMORY
;
514 } __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
520 nsAccessNodeWrap::get_language(BSTR __RPC_FAR
*aLanguage
)
525 nsAutoString language
;
526 if (NS_FAILED(GetLanguage(language
))) {
530 if (language
.IsEmpty())
533 *aLanguage
= ::SysAllocStringLen(language
.get(), language
.Length());
535 return E_OUTOFMEMORY
;
537 } __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
543 nsAccessNodeWrap::get_localInterface(
544 /* [out] */ void __RPC_FAR
*__RPC_FAR
*localInterface
)
547 *localInterface
= static_cast<nsIAccessNode
*>(this);
549 } __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
553 void nsAccessNodeWrap::InitAccessibility()
555 nsCOMPtr
<nsIPrefBranch
> prefBranch(do_GetService(NS_PREFSERVICE_CONTRACTID
));
557 prefBranch
->GetBoolPref("accessibility.disableenumvariant", &gIsEnumVariantSupportDisabled
);
561 gmUserLib
=::LoadLibraryW(L
"USER32.DLL");
565 if (!gmNotifyWinEvent
)
566 gmNotifyWinEvent
= (LPFNNOTIFYWINEVENT
)GetProcAddress(gmUserLib
,"NotifyWinEvent");
567 if (!gmGetGUIThreadInfo
)
568 gmGetGUIThreadInfo
= (LPFNGETGUITHREADINFO
)GetProcAddress(gmUserLib
,"GetGUIThreadInfo");
571 DoATSpecificProcessing();
573 nsAccessNode::InitXPAccessibility();
576 void nsAccessNodeWrap::ShutdownAccessibility()
578 NS_IF_RELEASE(gTextEvent
);
581 nsAccessNode::ShutdownXPAccessibility();
584 int nsAccessNodeWrap::FilterA11yExceptions(unsigned int aCode
, EXCEPTION_POINTERS
*aExceptionInfo
)
586 if (aCode
== EXCEPTION_ACCESS_VIOLATION
) {
587 #ifdef MOZ_CRASHREPORTER
588 // MSAA swallows crashes (because it is COM-based)
589 // but we still need to learn about those crashes so we can fix them
590 // Make sure to pass them to the crash reporter
591 nsCOMPtr
<nsICrashReporter
> crashReporter
=
592 do_GetService("@mozilla.org/toolkit/crash-reporter;1");
594 crashReporter
->WriteMinidumpForException(aExceptionInfo
);
599 NS_NOTREACHED("We should only be catching crash exceptions");
601 return EXCEPTION_CONTINUE_SEARCH
;
605 GetHRESULT(nsresult aResult
)
611 case NS_ERROR_INVALID_ARG
: case NS_ERROR_INVALID_POINTER
:
614 case NS_ERROR_OUT_OF_MEMORY
:
615 return E_OUTOFMEMORY
;
617 case NS_ERROR_NOT_IMPLEMENTED
:
625 PRBool
nsAccessNodeWrap::IsOnlyMsaaCompatibleJawsPresent()
627 HMODULE jhookhandle
= ::GetModuleHandleW(L
"jhook");
629 return PR_FALSE
; // No JAWS, or some other screen reader, use IA2
631 PRUnichar fileName
[MAX_PATH
];
632 ::GetModuleFileNameW(jhookhandle
, fileName
, MAX_PATH
);
635 DWORD length
= ::GetFileVersionInfoSizeW(fileName
, &dummy
);
637 LPBYTE versionInfo
= new BYTE
[length
];
638 ::GetFileVersionInfoW(fileName
, 0, length
, versionInfo
);
641 VS_FIXEDFILEINFO
*fixedFileInfo
;
642 ::VerQueryValueW(versionInfo
, L
"\\", (LPVOID
*)&fixedFileInfo
, &uLen
);
643 DWORD dwFileVersionMS
= fixedFileInfo
->dwFileVersionMS
;
644 DWORD dwFileVersionLS
= fixedFileInfo
->dwFileVersionLS
;
645 delete [] versionInfo
;
647 DWORD dwLeftMost
= HIWORD(dwFileVersionMS
);
648 // DWORD dwSecondLeft = LOWORD(dwFileVersionMS);
649 DWORD dwSecondRight
= HIWORD(dwFileVersionLS
);
650 // DWORD dwRightMost = LOWORD(dwFileVersionLS);
652 return (dwLeftMost
< 8
653 || (dwLeftMost
== 8 && dwSecondRight
< 2173));
656 void nsAccessNodeWrap::TurnOffNewTabSwitchingForJawsAndWE()
658 HMODULE srHandle
= ::GetModuleHandleW(L
"jhook");
660 // No JAWS, try Window-Eyes
661 srHandle
= ::GetModuleHandleW(L
"gwm32inc");
663 // no screen reader we're interested in. Bail out.
668 // Check to see if the pref for disallowing CtrlTab is already set.
671 nsCOMPtr
<nsIPrefBranch
> prefs (do_GetService(NS_PREFSERVICE_CONTRACTID
));
673 PRBool hasDisallowNewCtrlTabPref
= PR_FALSE
;
674 nsresult rv
= prefs
->PrefHasUserValue(CTRLTAB_DISALLOW_FOR_SCREEN_READERS_PREF
,
675 &hasDisallowNewCtrlTabPref
);
676 if (NS_SUCCEEDED(rv
) && hasDisallowNewCtrlTabPref
) {
677 // This pref has been set before. There is no default for it.
678 // Do nothing further, respect the setting that's there.
679 // That way, if noone touches it, it'll stay on after toggled once.
680 // If someone decided to turn it off, we respect that, too.
684 // Value has never been set, set it.
685 prefs
->SetBoolPref(CTRLTAB_DISALLOW_FOR_SCREEN_READERS_PREF
, PR_TRUE
);
689 void nsAccessNodeWrap::DoATSpecificProcessing()
691 if (IsOnlyMsaaCompatibleJawsPresent())
692 // All versions below 8.0.2173 are not compatible
693 gIsIA2Disabled
= PR_TRUE
;
695 TurnOffNewTabSwitchingForJawsAndWE();