Bug 527003 - separated out xpcom parts of nsAccessibilityService.
MozReview-Commit-ID: ALiZp5hUXK1
---
accessible/base/moz.build | 1 +
accessible/base/nsAccessibilityService.cpp | 285 +----------------
accessible/base/nsAccessibilityService.h | 45 ++-
accessible/interfaces/nsIAccessibilityService.idl | 10 -
accessible/xpcom/moz.build | 2 +
accessible/xpcom/xpcAccessibilityService.cpp | 356 ++++++++++++++++++++++
accessible/xpcom/xpcAccessibilityService.h | 41 +++
dom/ipc/ContentChild.cpp | 2 +-
layout/build/nsLayoutModule.cpp | 4 +-
layout/inspector/inDOMView.cpp | 2 +-
widget/gtk/nsWindow.cpp | 2 +-
widget/nsBaseWidget.cpp | 2 +-
widget/windows/nsWindow.cpp | 2 +-
13 files changed, 448 insertions(+), 306 deletions(-)
create mode 100644 accessible/xpcom/xpcAccessibilityService.cpp
create mode 100644 accessible/xpcom/xpcAccessibilityService.h
--- a/accessible/base/moz.build
+++ b/accessible/base/moz.build
@@ -13,16 +13,17 @@ EXPORTS.mozilla.a11y += [
'AccTypes.h',
'DocManager.h',
'FocusManager.h',
'Platform.h',
'RelationType.h',
'Role.h',
'SelectionManager.h',
'States.h',
+ 'Statistics.h',
]
if CONFIG['MOZ_DEBUG']:
EXPORTS.mozilla.a11y += [
'Logging.h',
]
UNIFIED_SOURCES += [
--- a/accessible/base/nsAccessibilityService.cpp
+++ b/accessible/base/nsAccessibilityService.cpp
@@ -15,17 +15,16 @@
#include "HTMLElementAccessibles.h"
#include "HTMLImageMapAccessible.h"
#include "HTMLLinkAccessible.h"
#include "HTMLListAccessible.h"
#include "HTMLSelectAccessible.h"
#include "HTMLTableAccessibleWrap.h"
#include "HyperTextAccessibleWrap.h"
#include "RootAccessible.h"
-#include "nsAccessiblePivot.h"
#include "nsAccUtils.h"
#include "nsArrayUtils.h"
#include "nsAttrName.h"
#include "nsEventShell.h"
#include "nsIURI.h"
#include "OuterDocAccessible.h"
#include "Platform.h"
#include "Role.h"
@@ -63,17 +62,16 @@
#include "nsPluginFrame.h"
#include "nsSVGPathGeometryFrame.h"
#include "nsTreeBodyFrame.h"
#include "nsTreeColumns.h"
#include "nsTreeUtils.h"
#include "nsXBLPrototypeBinding.h"
#include "nsXBLBinding.h"
#include "mozilla/ArrayUtils.h"
-#include "mozilla/dom/DOMStringList.h"
#include "mozilla/Preferences.h"
#include "mozilla/Services.h"
#include "nsDeckFrame.h"
#ifdef MOZ_XUL
#include "XULAlertAccessible.h"
#include "XULColorPickerAccessible.h"
#include "XULComboboxAccessible.h"
@@ -335,17 +333,16 @@ nsAccessibilityService::ListenersChanged
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// nsISupports
NS_IMPL_ISUPPORTS_INHERITED(nsAccessibilityService,
DocManager,
- nsIAccessibilityService,
nsIObserver,
nsIListenerChangeListener,
nsISelectionListener) // from SelectionManager
////////////////////////////////////////////////////////////////////////////////
// nsIObserver
NS_IMETHODIMP
@@ -726,288 +723,48 @@ void
nsAccessibilityService::RecreateAccessible(nsIPresShell* aPresShell,
nsIContent* aContent)
{
DocAccessible* document = GetDocAccessible(aPresShell);
if (document)
document->RecreateAccessible(aContent);
}
-////////////////////////////////////////////////////////////////////////////////
-// nsIAccessibilityService
-
-NS_IMETHODIMP
-nsAccessibilityService::GetApplicationAccessible(nsIAccessible** aAccessibleApplication)
-{
- NS_ENSURE_ARG_POINTER(aAccessibleApplication);
-
- NS_IF_ADDREF(*aAccessibleApplication = XPCApplicationAcc());
- return NS_OK;
-}
-
-NS_IMETHODIMP
-nsAccessibilityService::GetAccessibleFor(nsIDOMNode *aNode,
- nsIAccessible **aAccessible)
-{
- NS_ENSURE_ARG_POINTER(aAccessible);
- *aAccessible = nullptr;
- if (!aNode)
- return NS_OK;
-
- nsCOMPtr<nsINode> node(do_QueryInterface(aNode));
- if (!node)
- return NS_ERROR_INVALID_ARG;
-
- DocAccessible* document = GetDocAccessible(node->OwnerDoc());
- if (document)
- NS_IF_ADDREF(*aAccessible = ToXPC(document->GetAccessible(node)));
-
- return NS_OK;
-}
-
-NS_IMETHODIMP
+void
nsAccessibilityService::GetStringRole(uint32_t aRole, nsAString& aString)
{
#define ROLE(geckoRole, stringRole, atkRole, \
macRole, msaaRole, ia2Role, nameRule) \
case roles::geckoRole: \
CopyUTF8toUTF16(stringRole, aString); \
- return NS_OK;
+ return;
switch (aRole) {
#include "RoleMap.h"
default:
aString.AssignLiteral("unknown");
- return NS_OK;
+ return;
}
#undef ROLE
}
-NS_IMETHODIMP
-nsAccessibilityService::GetStringStates(uint32_t aState, uint32_t aExtraState,
- nsISupports **aStringStates)
-{
- RefPtr<DOMStringList> stringStates = new DOMStringList();
-
- uint64_t state = nsAccUtils::To64State(aState, aExtraState);
-
- // states
- if (state & states::UNAVAILABLE)
- stringStates->Add(NS_LITERAL_STRING("unavailable"));
- if (state & states::SELECTED)
- stringStates->Add(NS_LITERAL_STRING("selected"));
- if (state & states::FOCUSED)
- stringStates->Add(NS_LITERAL_STRING("focused"));
- if (state & states::PRESSED)
- stringStates->Add(NS_LITERAL_STRING("pressed"));
- if (state & states::CHECKED)
- stringStates->Add(NS_LITERAL_STRING("checked"));
- if (state & states::MIXED)
- stringStates->Add(NS_LITERAL_STRING("mixed"));
- if (state & states::READONLY)
- stringStates->Add(NS_LITERAL_STRING("readonly"));
- if (state & states::HOTTRACKED)
- stringStates->Add(NS_LITERAL_STRING("hottracked"));
- if (state & states::DEFAULT)
- stringStates->Add(NS_LITERAL_STRING("default"));
- if (state & states::EXPANDED)
- stringStates->Add(NS_LITERAL_STRING("expanded"));
- if (state & states::COLLAPSED)
- stringStates->Add(NS_LITERAL_STRING("collapsed"));
- if (state & states::BUSY)
- stringStates->Add(NS_LITERAL_STRING("busy"));
- if (state & states::FLOATING)
- stringStates->Add(NS_LITERAL_STRING("floating"));
- if (state & states::ANIMATED)
- stringStates->Add(NS_LITERAL_STRING("animated"));
- if (state & states::INVISIBLE)
- stringStates->Add(NS_LITERAL_STRING("invisible"));
- if (state & states::OFFSCREEN)
- stringStates->Add(NS_LITERAL_STRING("offscreen"));
- if (state & states::SIZEABLE)
- stringStates->Add(NS_LITERAL_STRING("sizeable"));
- if (state & states::MOVEABLE)
- stringStates->Add(NS_LITERAL_STRING("moveable"));
- if (state & states::SELFVOICING)
- stringStates->Add(NS_LITERAL_STRING("selfvoicing"));
- if (state & states::FOCUSABLE)
- stringStates->Add(NS_LITERAL_STRING("focusable"));
- if (state & states::SELECTABLE)
- stringStates->Add(NS_LITERAL_STRING("selectable"));
- if (state & states::LINKED)
- stringStates->Add(NS_LITERAL_STRING("linked"));
- if (state & states::TRAVERSED)
- stringStates->Add(NS_LITERAL_STRING("traversed"));
- if (state & states::MULTISELECTABLE)
- stringStates->Add(NS_LITERAL_STRING("multiselectable"));
- if (state & states::EXTSELECTABLE)
- stringStates->Add(NS_LITERAL_STRING("extselectable"));
- if (state & states::PROTECTED)
- stringStates->Add(NS_LITERAL_STRING("protected"));
- if (state & states::HASPOPUP)
- stringStates->Add(NS_LITERAL_STRING("haspopup"));
- if (state & states::REQUIRED)
- stringStates->Add(NS_LITERAL_STRING("required"));
- if (state & states::ALERT)
- stringStates->Add(NS_LITERAL_STRING("alert"));
- if (state & states::INVALID)
- stringStates->Add(NS_LITERAL_STRING("invalid"));
- if (state & states::CHECKABLE)
- stringStates->Add(NS_LITERAL_STRING("checkable"));
-
- // extraStates
- if (state & states::SUPPORTS_AUTOCOMPLETION)
- stringStates->Add(NS_LITERAL_STRING("autocompletion"));
- if (state & states::DEFUNCT)
- stringStates->Add(NS_LITERAL_STRING("defunct"));
- if (state & states::SELECTABLE_TEXT)
- stringStates->Add(NS_LITERAL_STRING("selectable text"));
- if (state & states::EDITABLE)
- stringStates->Add(NS_LITERAL_STRING("editable"));
- if (state & states::ACTIVE)
- stringStates->Add(NS_LITERAL_STRING("active"));
- if (state & states::MODAL)
- stringStates->Add(NS_LITERAL_STRING("modal"));
- if (state & states::MULTI_LINE)
- stringStates->Add(NS_LITERAL_STRING("multi line"));
- if (state & states::HORIZONTAL)
- stringStates->Add(NS_LITERAL_STRING("horizontal"));
- if (state & states::OPAQUE1)
- stringStates->Add(NS_LITERAL_STRING("opaque"));
- if (state & states::SINGLE_LINE)
- stringStates->Add(NS_LITERAL_STRING("single line"));
- if (state & states::TRANSIENT)
- stringStates->Add(NS_LITERAL_STRING("transient"));
- if (state & states::VERTICAL)
- stringStates->Add(NS_LITERAL_STRING("vertical"));
- if (state & states::STALE)
- stringStates->Add(NS_LITERAL_STRING("stale"));
- if (state & states::ENABLED)
- stringStates->Add(NS_LITERAL_STRING("enabled"));
- if (state & states::SENSITIVE)
- stringStates->Add(NS_LITERAL_STRING("sensitive"));
- if (state & states::EXPANDABLE)
- stringStates->Add(NS_LITERAL_STRING("expandable"));
-
- //unknown states
- if (!stringStates->Length())
- stringStates->Add(NS_LITERAL_STRING("unknown"));
-
- stringStates.forget(aStringStates);
- return NS_OK;
-}
-
-// nsIAccessibilityService::getStringEventType()
-NS_IMETHODIMP
+void
nsAccessibilityService::GetStringEventType(uint32_t aEventType,
nsAString& aString)
{
NS_ASSERTION(nsIAccessibleEvent::EVENT_LAST_ENTRY == ArrayLength(kEventTypeNames),
"nsIAccessibleEvent constants are out of sync to kEventTypeNames");
if (aEventType >= ArrayLength(kEventTypeNames)) {
aString.AssignLiteral("unknown");
- return NS_OK;
+ return;
}
CopyUTF8toUTF16(kEventTypeNames[aEventType], aString);
- return NS_OK;
-}
-
-// nsIAccessibilityService::getStringRelationType()
-NS_IMETHODIMP
-nsAccessibilityService::GetStringRelationType(uint32_t aRelationType,
- nsAString& aString)
-{
- NS_ENSURE_ARG(aRelationType <= static_cast<uint32_t>(RelationType::LAST));
-
-#define RELATIONTYPE(geckoType, geckoTypeName, atkType, msaaType, ia2Type) \
- case RelationType::geckoType: \
- aString.AssignLiteral(geckoTypeName); \
- return NS_OK;
-
- RelationType relationType = static_cast<RelationType>(aRelationType);
- switch (relationType) {
-#include "RelationTypeMap.h"
- default:
- aString.AssignLiteral("unknown");
- return NS_OK;
- }
-
-#undef RELATIONTYPE
-}
-
-NS_IMETHODIMP
-nsAccessibilityService::GetAccessibleFromCache(nsIDOMNode* aNode,
- nsIAccessible** aAccessible)
-{
- NS_ENSURE_ARG_POINTER(aAccessible);
- *aAccessible = nullptr;
- if (!aNode)
- return NS_OK;
-
- nsCOMPtr<nsINode> node(do_QueryInterface(aNode));
- if (!node)
- return NS_ERROR_INVALID_ARG;
-
- // Search for an accessible in each of our per document accessible object
- // caches. If we don't find it, and the given node is itself a document, check
- // our cache of document accessibles (document cache). Note usually shutdown
- // document accessibles are not stored in the document cache, however an
- // "unofficially" shutdown document (i.e. not from DocManager) can still
- // exist in the document cache.
- Accessible* accessible = FindAccessibleInCache(node);
- if (!accessible) {
- nsCOMPtr<nsIDocument> document(do_QueryInterface(node));
- if (document)
- accessible = GetExistingDocAccessible(document);
- }
-
- NS_IF_ADDREF(*aAccessible = ToXPC(accessible));
- return NS_OK;
-}
-
-NS_IMETHODIMP
-nsAccessibilityService::CreateAccessiblePivot(nsIAccessible* aRoot,
- nsIAccessiblePivot** aPivot)
-{
- NS_ENSURE_ARG_POINTER(aPivot);
- NS_ENSURE_ARG(aRoot);
- *aPivot = nullptr;
-
- Accessible* accessibleRoot = aRoot->ToInternalAccessible();
- NS_ENSURE_TRUE(accessibleRoot, NS_ERROR_INVALID_ARG);
-
- nsAccessiblePivot* pivot = new nsAccessiblePivot(accessibleRoot);
- NS_ADDREF(*aPivot = pivot);
-
- return NS_OK;
-}
-
-NS_IMETHODIMP
-nsAccessibilityService::SetLogging(const nsACString& aModules)
-{
-#ifdef A11Y_LOG
- logging::Enable(PromiseFlatCString(aModules));
-#endif
- return NS_OK;
-}
-
-NS_IMETHODIMP
-nsAccessibilityService::IsLogged(const nsAString& aModule, bool* aIsLogged)
-{
- NS_ENSURE_ARG_POINTER(aIsLogged);
- *aIsLogged = false;
-
-#ifdef A11Y_LOG
- *aIsLogged = logging::IsEnabled(aModule);
-#endif
-
- return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// nsAccessibilityService public
Accessible*
nsAccessibilityService::CreateAccessible(nsINode* aNode,
Accessible* aContext,
@@ -1789,48 +1546,16 @@ nsAccessibilityService::HasAccessible(ns
DocAccessible* document = GetDocAccessible(node->OwnerDoc());
if (!document)
return false;
return document->HasAccessible(node);
}
////////////////////////////////////////////////////////////////////////////////
-// NS_GetAccessibilityService
-////////////////////////////////////////////////////////////////////////////////
-
-/**
- * Return accessibility service; creating one if necessary.
- */
-nsresult
-NS_GetAccessibilityService(nsAccessibilityService** aResult)
-{
- NS_ENSURE_TRUE(aResult, NS_ERROR_NULL_POINTER);
- *aResult = nullptr;
-
- if (nsAccessibilityService::gAccessibilityService) {
- NS_ADDREF(*aResult = nsAccessibilityService::gAccessibilityService);
- return NS_OK;
- }
-
- RefPtr<nsAccessibilityService> service = new nsAccessibilityService();
- NS_ENSURE_TRUE(service, NS_ERROR_OUT_OF_MEMORY);
-
- if (!service->Init()) {
- service->Shutdown();
- return NS_ERROR_FAILURE;
- }
-
- statistics::A11yInitialized();
-
- NS_ADDREF(*aResult = service);
- return NS_OK;
-}
-
-////////////////////////////////////////////////////////////////////////////////
// nsAccessibilityService private (DON'T put methods here)
#ifdef MOZ_XUL
already_AddRefed<Accessible>
nsAccessibilityService::CreateAccessibleForXULTree(nsIContent* aContent,
DocAccessible* aDoc)
{
nsIContent* child = nsTreeUtils::GetDescendantChild(aContent,
--- a/accessible/base/nsAccessibilityService.h
+++ b/accessible/base/nsAccessibilityService.h
@@ -1,22 +1,21 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef __nsAccessibilityService_h__
#define __nsAccessibilityService_h__
-#include "nsIAccessibilityService.h"
-
#include "mozilla/a11y/DocManager.h"
#include "mozilla/a11y/FocusManager.h"
#include "mozilla/a11y/Role.h"
#include "mozilla/a11y/SelectionManager.h"
+#include "mozilla/a11y/Statistics.h"
#include "mozilla/Preferences.h"
#include "nsIObserver.h"
#include "nsIEventListenerService.h"
class nsImageFrame;
class nsIArray;
class nsIPersistentProperties;
@@ -63,33 +62,31 @@ struct MarkupMapInfo {
};
} // namespace a11y
} // namespace mozilla
class nsAccessibilityService final : public mozilla::a11y::DocManager,
public mozilla::a11y::FocusManager,
public mozilla::a11y::SelectionManager,
- public nsIAccessibilityService,
public nsIListenerChangeListener,
public nsIObserver
{
public:
typedef mozilla::a11y::Accessible Accessible;
typedef mozilla::a11y::DocAccessible DocAccessible;
// nsIListenerChangeListener
NS_IMETHOD ListenersChanged(nsIArray* aEventChanges) override;
protected:
virtual ~nsAccessibilityService();
public:
NS_DECL_ISUPPORTS_INHERITED
- NS_DECL_NSIACCESSIBILITYSERVICE
NS_DECL_NSIOBSERVER
virtual Accessible* GetRootDocumentAccessible(nsIPresShell* aPresShell,
bool aCanCreate);
already_AddRefed<Accessible>
CreatePluginAccessible(nsPluginFrame* aFrame, nsIContent* aContent,
Accessible* aContext);
@@ -97,16 +94,26 @@ public:
* Adds/remove ATK root accessible for gtk+ native window to/from children
* of the application accessible.
*/
virtual Accessible* AddNativeRootAccessible(void* aAtkAccessible);
virtual void RemoveNativeRootAccessible(Accessible* aRootAccessible);
virtual bool HasAccessible(nsIDOMNode* aDOMNode);
+ /**
+ * Get a string equivalent for an accessilbe role value.
+ */
+ void GetStringRole(uint32_t aRole, nsAString& aString);
+
+ /**
+ * Get a string equivalent for an accessible event value.
+ */
+ void GetStringEventType(uint32_t aEventType, nsAString& aString);
+
// nsAccesibilityService
/**
* Notification used to update the accessible tree when deck panel is
* switched.
*/
void DeckPanelSwitched(nsIPresShell* aPresShell, nsIContent* aDeckNode,
nsIFrame* aPrevBoxFrame, nsIFrame* aCurrentBoxFrame);
@@ -199,17 +206,17 @@ public:
/**
* Set the object attribute defined by markup for the given element.
*/
void MarkupAttributes(const nsIContent* aContent,
nsIPersistentProperties* aAttributes) const;
private:
// nsAccessibilityService creation is controlled by friend
- // NS_GetAccessibilityService, keep constructors private.
+ // GetOrCreateAccService, keep constructors private.
nsAccessibilityService();
nsAccessibilityService(const nsAccessibilityService&);
nsAccessibilityService& operator =(const nsAccessibilityService&);
private:
/**
* Initialize accessibility service.
*/
@@ -255,50 +262,71 @@ private:
/**
* Indicates whether accessibility service was shutdown.
*/
static bool gIsShutdown;
nsDataHashtable<nsPtrHashKey<const nsIAtom>, const mozilla::a11y::MarkupMapInfo*> mMarkupMaps;
friend nsAccessibilityService* GetAccService();
+ friend nsAccessibilityService* GetOrCreateAccService();
friend mozilla::a11y::FocusManager* mozilla::a11y::FocusMgr();
friend mozilla::a11y::SelectionManager* mozilla::a11y::SelectionMgr();
friend mozilla::a11y::ApplicationAccessible* mozilla::a11y::ApplicationAcc();
friend mozilla::a11y::xpcAccessibleApplication* mozilla::a11y::XPCApplicationAcc();
-
- friend nsresult NS_GetAccessibilityService(nsAccessibilityService** aResult);
};
/**
* Return the accessibility service instance. (Handy global function)
*/
inline nsAccessibilityService*
GetAccService()
{
return nsAccessibilityService::gAccessibilityService;
}
/**
+ * Return accessibility service instance; creating one if necessary.
+ */
+inline nsAccessibilityService*
+GetOrCreateAccService()
+{
+ if (nsAccessibilityService::gAccessibilityService) {
+ return nsAccessibilityService::gAccessibilityService;
+ }
+
+ RefPtr<nsAccessibilityService> service = new nsAccessibilityService();
+
+ if (!service->Init()) {
+ service->Shutdown();
+ return nullptr;
+ }
+
+ mozilla::a11y::statistics::A11yInitialized();
+ NS_ADDREF(service);
+ return service;
+}
+
+/**
* Return true if we're in a content process and not B2G.
*/
inline bool
IPCAccessibilityActive()
{
#ifdef MOZ_B2G
return false;
#else
return XRE_IsContentProcess() &&
mozilla::Preferences::GetBool("accessibility.ipc_architecture.enabled", true);
#endif
}
/**
* Map nsIAccessibleEvents constants to strings. Used by
- * nsIAccessibilityService::getStringEventType() method.
+ * nsAccessibilityService::GetStringEventType() method.
*/
static const char kEventTypeNames[][40] = {
"unknown", //
"show", // EVENT_SHOW
"hide", // EVENT_HIDE
"reorder", // EVENT_REORDER
"active decendent change", // EVENT_ACTIVE_DECENDENT_CHANGED
"focus", // EVENT_FOCUS
@@ -382,9 +410,8 @@ static const char kEventTypeNames[][40]
"hypertext changed", // EVENT_HYPERTEXT_CHANGED
"hypertext links count changed", // EVENT_HYPERTEXT_NLINKS_CHANGED
"object attribute changed", // EVENT_OBJECT_ATTRIBUTE_CHANGED
"virtual cursor changed", // EVENT_VIRTUALCURSOR_CHANGED
"text value change", // EVENT_TEXT_VALUE_CHANGE
};
#endif
-
--- a/accessible/interfaces/nsIAccessibilityService.idl
+++ b/accessible/interfaces/nsIAccessibilityService.idl
@@ -93,18 +93,8 @@ interface nsIAccessibilityService : nsIS
*/
void setLogging(in ACString aModules);
/**
* Return true if the given module is logged.
*/
boolean isLogged(in AString aModule);
};
-
-
-%{ C++
-
-// for component registration
-// {DE401C37-9A7F-4278-A6F8-3DE2833989EF}
-#define NS_ACCESSIBILITY_SERVICE_CID \
-{ 0xde401c37, 0x9a7f, 0x4278, { 0xa6, 0xf8, 0x3d, 0xe2, 0x83, 0x39, 0x89, 0xef } }
-
-%}
--- a/accessible/xpcom/moz.build
+++ b/accessible/xpcom/moz.build
@@ -1,16 +1,17 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
UNIFIED_SOURCES += [
'nsAccessibleRelation.cpp',
+ 'xpcAccessibilityService.cpp',
'xpcAccessible.cpp',
'xpcAccessibleApplication.cpp',
'xpcAccessibleDocument.cpp',
'xpcAccessibleGeneric.cpp',
'xpcAccessibleHyperLink.cpp',
'xpcAccessibleHyperText.cpp',
'xpcAccessibleImage.cpp',
'xpcAccessibleSelectable.cpp',
@@ -21,16 +22,17 @@ UNIFIED_SOURCES += [
]
SOURCES += [
'!xpcAccEvents.cpp',
]
EXPORTS += [
'!xpcAccEvents.h',
+ 'xpcAccessibilityService.h',
]
LOCAL_INCLUDES += [
'/accessible/base',
'/accessible/generic',
]
if 'gtk' in CONFIG['MOZ_WIDGET_TOOLKIT']:
new file mode 100644
--- /dev/null
+++ b/accessible/xpcom/xpcAccessibilityService.cpp
@@ -0,0 +1,356 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "xpcAccessibilityService.h"
+
+#include "mozilla/dom/DOMStringList.h"
+#include "nsAccessiblePivot.h"
+#include "nsAccessibilityService.h"
+#include "nsAccUtils.h"
+
+#ifdef A11Y_LOG
+#include "Logging.h"
+#endif
+
+using namespace mozilla;
+using namespace mozilla::a11y;
+using namespace mozilla::dom;
+
+xpcAccessibilityService *xpcAccessibilityService::accessibilityService = nullptr;
+
+////////////////////////////////////////////////////////////////////////////////
+// nsISupports
+
+NS_IMPL_ISUPPORTS(xpcAccessibilityService, nsIAccessibilityService)
+
+NS_IMETHODIMP
+xpcAccessibilityService::GetApplicationAccessible(nsIAccessible** aAccessibleApplication)
+{
+ NS_ENSURE_ARG_POINTER(aAccessibleApplication);
+
+ NS_IF_ADDREF(*aAccessibleApplication = XPCApplicationAcc());
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibilityService::GetAccessibleFor(nsIDOMNode *aNode,
+ nsIAccessible **aAccessible)
+{
+ NS_ENSURE_ARG_POINTER(aAccessible);
+ *aAccessible = nullptr;
+ if (!aNode) {
+ return NS_OK;
+ }
+
+ nsCOMPtr<nsINode> node(do_QueryInterface(aNode));
+ if (!node) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ DocAccessible* document = GetAccService()->GetDocAccessible(node->OwnerDoc());
+ if (document) {
+ NS_IF_ADDREF(*aAccessible = ToXPC(document->GetAccessible(node)));
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibilityService::GetStringRole(uint32_t aRole, nsAString& aString)
+{
+ GetAccService()->GetStringRole(aRole, aString);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibilityService::GetStringStates(uint32_t aState, uint32_t aExtraState,
+ nsISupports **aStringStates)
+{
+ RefPtr<DOMStringList> stringStates = new DOMStringList();
+
+ uint64_t state = nsAccUtils::To64State(aState, aExtraState);
+
+ // states
+ if (state & states::UNAVAILABLE) {
+ stringStates->Add(NS_LITERAL_STRING("unavailable"));
+ }
+ if (state & states::SELECTED) {
+ stringStates->Add(NS_LITERAL_STRING("selected"));
+ }
+ if (state & states::FOCUSED) {
+ stringStates->Add(NS_LITERAL_STRING("focused"));
+ }
+ if (state & states::PRESSED) {
+ stringStates->Add(NS_LITERAL_STRING("pressed"));
+ }
+ if (state & states::CHECKED) {
+ stringStates->Add(NS_LITERAL_STRING("checked"));
+ }
+ if (state & states::MIXED) {
+ stringStates->Add(NS_LITERAL_STRING("mixed"));
+ }
+ if (state & states::READONLY) {
+ stringStates->Add(NS_LITERAL_STRING("readonly"));
+ }
+ if (state & states::HOTTRACKED) {
+ stringStates->Add(NS_LITERAL_STRING("hottracked"));
+ }
+ if (state & states::DEFAULT) {
+ stringStates->Add(NS_LITERAL_STRING("default"));
+ }
+ if (state & states::EXPANDED) {
+ stringStates->Add(NS_LITERAL_STRING("expanded"));
+ }
+ if (state & states::COLLAPSED) {
+ stringStates->Add(NS_LITERAL_STRING("collapsed"));
+ }
+ if (state & states::BUSY) {
+ stringStates->Add(NS_LITERAL_STRING("busy"));
+ }
+ if (state & states::FLOATING) {
+ stringStates->Add(NS_LITERAL_STRING("floating"));
+ }
+ if (state & states::ANIMATED) {
+ stringStates->Add(NS_LITERAL_STRING("animated"));
+ }
+ if (state & states::INVISIBLE) {
+ stringStates->Add(NS_LITERAL_STRING("invisible"));
+ }
+ if (state & states::OFFSCREEN) {
+ stringStates->Add(NS_LITERAL_STRING("offscreen"));
+ }
+ if (state & states::SIZEABLE) {
+ stringStates->Add(NS_LITERAL_STRING("sizeable"));
+ }
+ if (state & states::MOVEABLE) {
+ stringStates->Add(NS_LITERAL_STRING("moveable"));
+ }
+ if (state & states::SELFVOICING) {
+ stringStates->Add(NS_LITERAL_STRING("selfvoicing"));
+ }
+ if (state & states::FOCUSABLE) {
+ stringStates->Add(NS_LITERAL_STRING("focusable"));
+ }
+ if (state & states::SELECTABLE) {
+ stringStates->Add(NS_LITERAL_STRING("selectable"));
+ }
+ if (state & states::LINKED) {
+ stringStates->Add(NS_LITERAL_STRING("linked"));
+ }
+ if (state & states::TRAVERSED) {
+ stringStates->Add(NS_LITERAL_STRING("traversed"));
+ }
+ if (state & states::MULTISELECTABLE) {
+ stringStates->Add(NS_LITERAL_STRING("multiselectable"));
+ }
+ if (state & states::EXTSELECTABLE) {
+ stringStates->Add(NS_LITERAL_STRING("extselectable"));
+ }
+ if (state & states::PROTECTED) {
+ stringStates->Add(NS_LITERAL_STRING("protected"));
+ }
+ if (state & states::HASPOPUP) {
+ stringStates->Add(NS_LITERAL_STRING("haspopup"));
+ }
+ if (state & states::REQUIRED) {
+ stringStates->Add(NS_LITERAL_STRING("required"));
+ }
+ if (state & states::ALERT) {
+ stringStates->Add(NS_LITERAL_STRING("alert"));
+ }
+ if (state & states::INVALID) {
+ stringStates->Add(NS_LITERAL_STRING("invalid"));
+ }
+ if (state & states::CHECKABLE) {
+ stringStates->Add(NS_LITERAL_STRING("checkable"));
+ }
+
+ // extraStates
+ if (state & states::SUPPORTS_AUTOCOMPLETION) {
+ stringStates->Add(NS_LITERAL_STRING("autocompletion"));
+ }
+ if (state & states::DEFUNCT) {
+ stringStates->Add(NS_LITERAL_STRING("defunct"));
+ }
+ if (state & states::SELECTABLE_TEXT) {
+ stringStates->Add(NS_LITERAL_STRING("selectable text"));
+ }
+ if (state & states::EDITABLE) {
+ stringStates->Add(NS_LITERAL_STRING("editable"));
+ }
+ if (state & states::ACTIVE) {
+ stringStates->Add(NS_LITERAL_STRING("active"));
+ }
+ if (state & states::MODAL) {
+ stringStates->Add(NS_LITERAL_STRING("modal"));
+ }
+ if (state & states::MULTI_LINE) {
+ stringStates->Add(NS_LITERAL_STRING("multi line"));
+ }
+ if (state & states::HORIZONTAL) {
+ stringStates->Add(NS_LITERAL_STRING("horizontal"));
+ }
+ if (state & states::OPAQUE1) {
+ stringStates->Add(NS_LITERAL_STRING("opaque"));
+ }
+ if (state & states::SINGLE_LINE) {
+ stringStates->Add(NS_LITERAL_STRING("single line"));
+ }
+ if (state & states::TRANSIENT) {
+ stringStates->Add(NS_LITERAL_STRING("transient"));
+ }
+ if (state & states::VERTICAL) {
+ stringStates->Add(NS_LITERAL_STRING("vertical"));
+ }
+ if (state & states::STALE) {
+ stringStates->Add(NS_LITERAL_STRING("stale"));
+ }
+ if (state & states::ENABLED) {
+ stringStates->Add(NS_LITERAL_STRING("enabled"));
+ }
+ if (state & states::SENSITIVE) {
+ stringStates->Add(NS_LITERAL_STRING("sensitive"));
+ }
+ if (state & states::EXPANDABLE) {
+ stringStates->Add(NS_LITERAL_STRING("expandable"));
+ }
+
+ //unknown states
+ if (!stringStates->Length()) {
+ stringStates->Add(NS_LITERAL_STRING("unknown"));
+ }
+
+ stringStates.forget(aStringStates);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibilityService::GetStringEventType(uint32_t aEventType,
+ nsAString& aString)
+{
+ GetAccService()->GetStringEventType(aEventType, aString);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibilityService::GetStringRelationType(uint32_t aRelationType,
+ nsAString& aString)
+{
+ NS_ENSURE_ARG(aRelationType <= static_cast<uint32_t>(RelationType::LAST));
+
+#define RELATIONTYPE(geckoType, geckoTypeName, atkType, msaaType, ia2Type) \
+ case RelationType::geckoType: \
+ aString.AssignLiteral(geckoTypeName); \
+ return NS_OK;
+
+ RelationType relationType = static_cast<RelationType>(aRelationType);
+ switch (relationType) {
+#include "RelationTypeMap.h"
+ default:
+ aString.AssignLiteral("unknown");
+ return NS_OK;
+ }
+
+#undef RELATIONTYPE
+}
+
+NS_IMETHODIMP
+xpcAccessibilityService::GetAccessibleFromCache(nsIDOMNode* aNode,
+ nsIAccessible** aAccessible)
+{
+ NS_ENSURE_ARG_POINTER(aAccessible);
+ *aAccessible = nullptr;
+ if (!aNode) {
+ return NS_OK;
+ }
+
+ nsCOMPtr<nsINode> node(do_QueryInterface(aNode));
+ if (!node) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ // Search for an accessible in each of our per document accessible object
+ // caches. If we don't find it, and the given node is itself a document, check
+ // our cache of document accessibles (document cache). Note usually shutdown
+ // document accessibles are not stored in the document cache, however an
+ // "unofficially" shutdown document (i.e. not from DocManager) can still
+ // exist in the document cache.
+ Accessible* accessible = GetAccService()->FindAccessibleInCache(node);
+ if (!accessible) {
+ nsCOMPtr<nsIDocument> document(do_QueryInterface(node));
+ if (document) {
+ accessible = mozilla::a11y::GetExistingDocAccessible(document);
+ }
+ }
+
+ NS_IF_ADDREF(*aAccessible = ToXPC(accessible));
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibilityService::CreateAccessiblePivot(nsIAccessible* aRoot,
+ nsIAccessiblePivot** aPivot)
+{
+ NS_ENSURE_ARG_POINTER(aPivot);
+ NS_ENSURE_ARG(aRoot);
+ *aPivot = nullptr;
+
+ Accessible* accessibleRoot = aRoot->ToInternalAccessible();
+ NS_ENSURE_TRUE(accessibleRoot, NS_ERROR_INVALID_ARG);
+
+ nsAccessiblePivot* pivot = new nsAccessiblePivot(accessibleRoot);
+ NS_ADDREF(*aPivot = pivot);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibilityService::SetLogging(const nsACString& aModules)
+{
+#ifdef A11Y_LOG
+ logging::Enable(PromiseFlatCString(aModules));
+#endif
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcAccessibilityService::IsLogged(const nsAString& aModule, bool* aIsLogged)
+{
+ NS_ENSURE_ARG_POINTER(aIsLogged);
+ *aIsLogged = false;
+
+#ifdef A11Y_LOG
+ *aIsLogged = logging::IsEnabled(aModule);
+#endif
+
+ return NS_OK;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// NS_GetAccessibilityService
+////////////////////////////////////////////////////////////////////////////////
+
+nsresult
+NS_GetAccessibilityService(nsIAccessibilityService** aResult)
+{
+ NS_ENSURE_TRUE(aResult, NS_ERROR_NULL_POINTER);
+ *aResult = nullptr;
+
+ if (xpcAccessibilityService::accessibilityService) {
+ NS_ADDREF(*aResult = xpcAccessibilityService::accessibilityService);
+
+ return NS_OK;
+ }
+
+ if (!GetAccService()) {
+ nsAccessibilityService* accService = GetOrCreateAccService();
+ }
+
+ RefPtr<xpcAccessibilityService> service = new xpcAccessibilityService();
+ NS_ENSURE_TRUE(service, NS_ERROR_OUT_OF_MEMORY);
+ xpcAccessibilityService::accessibilityService = service;
+ NS_ADDREF(*aResult = service);
+
+ return NS_OK;
+}
new file mode 100644
--- /dev/null
+++ b/accessible/xpcom/xpcAccessibilityService.h
@@ -0,0 +1,41 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_a11y_xpcAccessibilityService_h_
+#define mozilla_a11y_xpcAccessibilityService_h_
+
+#include "nsIAccessibilityService.h"
+
+class xpcAccessibilityService : public nsIAccessibilityService
+{
+
+public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIACCESSIBILITYSERVICE
+
+protected:
+ virtual ~xpcAccessibilityService() {}
+
+private:
+ // xpcAccessibilityService creation is controlled by friend
+ // NS_GetAccessibilityService, keep constructor private.
+ xpcAccessibilityService() {};
+
+ /**
+ * Reference for xpc accessibility service instance.
+ */
+ static xpcAccessibilityService* accessibilityService;
+
+ friend nsresult NS_GetAccessibilityService(nsIAccessibilityService** aResult);
+};
+
+// for component registration
+// {3b265b69-f813-48ff-880d-d88d101af404}
+#define NS_ACCESSIBILITY_SERVICE_CID \
+{ 0x3b265b69, 0xf813, 0x48ff, { 0x88, 0x0d, 0xd8, 0x8d, 0x10, 0x1a, 0xf4, 0x04 } }
+
+extern nsresult
+NS_GetAccessibilityService(nsIAccessibilityService** aResult);
+
+#endif
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -2569,17 +2569,17 @@ ContentChild::RecvFlushMemory(const nsSt
}
bool
ContentChild::RecvActivateA11y()
{
#ifdef ACCESSIBILITY
// Start accessibility in content process if it's running in chrome
// process.
- nsAccessibilityService* accService = GetAccService();
+ nsAccessibilityService* accService = GetOrCreateAccService();
#endif
return true;
}
bool
ContentChild::RecvGarbageCollect()
{
// Rebroadcast the "child-gc-request" so that workers will GC.
--- a/layout/build/nsLayoutModule.cpp
+++ b/layout/build/nsLayoutModule.cpp
@@ -672,19 +672,19 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(UDPSocket
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(GeckoMediaPluginService, GeckoMediaPluginService::GetGeckoMediaPluginService)
#ifdef MOZ_B2G
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsIHardwareKeyHandler,
HardwareKeyHandler::GetInstance)
#endif
#ifdef ACCESSIBILITY
-#include "nsAccessibilityService.h"
+#include "xpcAccessibilityService.h"
- MAKE_CTOR(CreateA11yService, nsAccessibilityService, NS_GetAccessibilityService)
+ MAKE_CTOR(CreateA11yService, nsIAccessibilityService, NS_GetAccessibilityService)
#endif
static nsresult
Construct_nsIScriptSecurityManager(nsISupports *aOuter, REFNSIID aIID,
void **aResult)
{
if (!aResult)
return NS_ERROR_NULL_POINTER;
--- a/layout/inspector/inDOMView.cpp
+++ b/layout/inspector/inDOMView.cpp
@@ -324,17 +324,17 @@ inDOMView::GetCellProperties(int32_t row
break;
case nsIDOMNode::NOTATION_NODE:
aProps.AppendLiteral("NOTATION_NODE");
break;
}
#ifdef ACCESSIBILITY
if (mShowAccessibleNodes) {
- nsAccessibilityService* accService = GetAccService();
+ nsAccessibilityService* accService = GetOrCreateAccService();
NS_ENSURE_TRUE(accService, NS_ERROR_FAILURE);
if (accService->HasAccessible(node->node))
aProps.AppendLiteral(" ACCESSIBLE_NODE");
}
#endif
return NS_OK;
--- a/widget/gtk/nsWindow.cpp
+++ b/widget/gtk/nsWindow.cpp
@@ -6285,17 +6285,17 @@ nsWindow::CreateRootAccessible()
void
nsWindow::DispatchEventToRootAccessible(uint32_t aEventType)
{
if (!a11y::ShouldA11yBeEnabled()) {
return;
}
- nsAccessibilityService* accService = GetAccService();
+ nsAccessibilityService* accService = GetOrCreateAccService();
if (!accService) {
return;
}
// Get the root document accessible and fire event to it.
a11y::Accessible* acc = GetRootAccessible();
if (acc) {
accService->FireAccessibleEvent(aEventType, acc);
--- a/widget/nsBaseWidget.cpp
+++ b/widget/nsBaseWidget.cpp
@@ -1896,17 +1896,17 @@ nsBaseWidget::GetRootAccessible()
// If container is null then the presshell is not active. This often happens
// when a preshell is being held onto for fastback.
nsPresContext* presContext = presShell->GetPresContext();
NS_ENSURE_TRUE(presContext->GetContainerWeak(), nullptr);
// Accessible creation might be not safe so use IsSafeToRunScript to
// make sure it's not created at unsafe times.
- nsAccessibilityService* accService = GetAccService();
+ nsAccessibilityService* accService = GetOrCreateAccService();
if (accService) {
#if defined(XP_WIN) || defined(XP_MACOSX) || defined(MOZ_WIDGET_GTK)
if (!mAccessibilityInUseFlag) {
mAccessibilityInUseFlag = true;
uint32_t now = PRTimeToSeconds(PR_Now());
Preferences::SetInt(kAccessibilityLastRunDatePref, now);
}
#endif
--- a/widget/windows/nsWindow.cpp
+++ b/widget/windows/nsWindow.cpp
@@ -6964,17 +6964,17 @@ nsWindow::GetAccessible()
return nullptr;
}
// In case of popup window return a popup accessible.
nsView* view = nsView::GetViewFor(this);
if (view) {
nsIFrame* frame = view->GetFrame();
if (frame && nsLayoutUtils::IsPopup(frame)) {
- nsAccessibilityService* accService = GetAccService();
+ nsAccessibilityService* accService = GetOrCreateAccService();
if (accService) {
a11y::DocAccessible* docAcc =
GetAccService()->GetDocAccessible(frame->PresContext()->PresShell());
if (docAcc) {
NS_LOG_WMGETOBJECT(this, mWnd,
docAcc->GetAccessibleOrDescendant(frame->GetContent()));
return docAcc->GetAccessibleOrDescendant(frame->GetContent());
}