Bug 553174 - expose nsIAccessibleApplication similar to IA2, r=marcoz, davidb

--HG--
rename : accessible/tests/mochitest/test_name_nsApplicationAcc.html => accessible/tests/mochitest/test_elm_nsApplicationAcc.html
This commit is contained in:
Alexander Surkov 2010-03-19 02:49:39 +08:00
Родитель 0d9ad15348
Коммит fcb54d49a2
17 изменённых файлов: 228 добавлений и 80 удалений

Просмотреть файл

@ -55,6 +55,7 @@ XPIDLSRCS = \
nsIAccessibilityService.idl \
nsIAccessibleRetrieval.idl \
nsIAccessible.idl \
nsIAccessibleApplication.idl \
nsIAccessibleRelation.idl \
nsIAccessibleRole.idl \
nsIAccessibleStates.idl \

Просмотреть файл

@ -0,0 +1,67 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Mozilla Corporation.
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Alexander Surkov <surkov.alexander@gmail.com> (original author)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsISupports.idl"
/**
* This interface is implemented by top level accessible object in hierarchy and
* provides information about application.
*/
[scriptable, uuid(79251626-387c-4531-89f3-680d31d6cf05)]
interface nsIAccessibleApplication : nsISupports
{
/**
* Returns the application name.
*/
readonly attribute DOMString appName;
/**
* Returns the application version.
*/
readonly attribute DOMString appVersion;
/**
* Returns the platform name.
*/
readonly attribute DOMString platformName;
/**
* Returns the platform version.
*/
readonly attribute DOMString platformVersion;
};

Просмотреть файл

@ -1095,10 +1095,10 @@ nsAccessibleWrap *GetAccessibleWrap(AtkObject *aAtkObj)
NS_ENSURE_TRUE(tmpAccWrap->GetAtkObject() == aAtkObj, nsnull);
nsRefPtr<nsApplicationAccessibleWrap> appAccWrap =
nsApplicationAccessible *applicationAcc =
nsAccessNode::GetApplicationAccessible();
nsAccessibleWrap* tmpAppAccWrap =
static_cast<nsAccessibleWrap*>(appAccWrap.get());
static_cast<nsAccessibleWrap*>(applicationAcc);
if (tmpAppAccWrap != tmpAccWrap && !tmpAccWrap->IsValidObject())
return nsnull;

Просмотреть файл

@ -446,11 +446,11 @@ mai_util_get_root(void)
return nsnull;
}
nsRefPtr<nsApplicationAccessibleWrap> root =
nsApplicationAccessible *applicationAcc =
nsAccessNode::GetApplicationAccessible();
if (root)
return root->GetAtkObject();
if (applicationAcc)
return applicationAcc->GetAtkObject();
return nsnull;
}

Просмотреть файл

@ -242,10 +242,10 @@ nsAccEvent::CaptureIsFromUserInput(EIsFromUserInput aIsFromUserInput)
// XXX: remove this hack during reorganization of 506907. Meanwhile we
// want to get rid an assertion for application accessible events which
// don't have DOM node (see bug 506206).
nsRefPtr<nsApplicationAccessibleWrap> applicationAcc =
nsApplicationAccessible *applicationAcc =
nsAccessNode::GetApplicationAccessible();
if (mAccessible != static_cast<nsIAccessible*>(applicationAcc.get()))
if (mAccessible != static_cast<nsIAccessible*>(applicationAcc))
NS_ASSERTION(targetNode, "There should always be a DOM node for an event");
}
#endif

Просмотреть файл

@ -81,7 +81,7 @@ PRBool nsAccessNode::gIsFormFillEnabled = PR_FALSE;
nsRefPtrHashtable<nsVoidPtrHashKey, nsDocAccessible>
nsAccessNode::gGlobalDocAccessibleCache;
nsApplicationAccessibleWrap *nsAccessNode::gApplicationAccessible = nsnull;
nsApplicationAccessible *nsAccessNode::gApplicationAccessible = nsnull;
/*
* Class nsAccessNode
@ -221,7 +221,7 @@ NS_IMETHODIMP nsAccessNode::GetOwnerWindow(void **aWindow)
return docAccessible->GetWindowHandle(aWindow);
}
already_AddRefed<nsApplicationAccessibleWrap>
nsApplicationAccessible*
nsAccessNode::GetApplicationAccessible()
{
NS_ASSERTION(!nsAccessibilityService::gIsShutdown,
@ -239,13 +239,12 @@ nsAccessNode::GetApplicationAccessible()
nsresult rv = gApplicationAccessible->Init();
if (NS_FAILED(rv)) {
gApplicationAccessible->Shutdown();
NS_RELEASE(gApplicationAccessible);
gApplicationAccessible = nsnull;
return nsnull;
}
}
NS_ADDREF(gApplicationAccessible); // Addref because we're a getter
return gApplicationAccessible;
}
@ -298,13 +297,15 @@ void nsAccessNode::ShutdownXPAccessibility()
NS_IF_RELEASE(gKeyStringBundle);
NS_IF_RELEASE(gLastFocusedNode);
nsApplicationAccessibleWrap::Unload();
ClearCache(gGlobalDocAccessibleCache);
// Release gApplicationAccessible after everything else is shutdown
// so we don't accidently create it again while tearing down root accessibles
NS_IF_RELEASE(gApplicationAccessible);
gApplicationAccessible = nsnull;
nsApplicationAccessibleWrap::Unload();
if (gApplicationAccessible) {
gApplicationAccessible->Shutdown();
NS_RELEASE(gApplicationAccessible);
}
NotifyA11yInitOrShutdown(PR_FALSE);
}

Просмотреть файл

@ -63,7 +63,7 @@ class nsIAccessibleDocument;
class nsIFrame;
class nsIDOMNodeList;
class nsRootAccessible;
class nsApplicationAccessibleWrap;
class nsApplicationAccessible;
class nsIDocShellTreeItem;
#define ACCESSIBLE_BUNDLE_URL "chrome://global-platform/locale/accessible.properties"
@ -118,10 +118,10 @@ class nsAccessNode: public nsIAccessNode
static void InitXPAccessibility();
static void ShutdownXPAccessibility();
/**
* Return an application accessible.
*/
static already_AddRefed<nsApplicationAccessibleWrap> GetApplicationAccessible();
/**
* Return an application accessible.
*/
static nsApplicationAccessible* GetApplicationAccessible();
already_AddRefed<nsRootAccessible> GetRootAccessible();
@ -216,7 +216,7 @@ protected:
gGlobalDocAccessibleCache;
private:
static nsApplicationAccessibleWrap *gApplicationAccessible;
static nsApplicationAccessible *gApplicationAccessible;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsAccessNode,

Просмотреть файл

@ -961,16 +961,12 @@ nsAccessibilityService::GetCachedAccessNode(nsIDOMNode *aNode,
// nsIAccessibleRetrieval
NS_IMETHODIMP
nsAccessibilityService::GetApplicationAccessible(nsIAccessible **aApplicationAccessible)
nsAccessibilityService::GetApplicationAccessible(nsIAccessible **aAccessibleApplication)
{
NS_ENSURE_ARG_POINTER(aApplicationAccessible);
*aApplicationAccessible = nsnull;
NS_ENSURE_ARG_POINTER(aAccessibleApplication);
nsRefPtr<nsApplicationAccessibleWrap> appAcc =
nsAccessNode::GetApplicationAccessible();
NS_ENSURE_STATE(appAcc);
return CallQueryInterface(appAcc, aApplicationAccessible);
NS_IF_ADDREF(*aAccessibleApplication = nsAccessNode::GetApplicationAccessible());
return NS_OK;
}
NS_IMETHODIMP
@ -2003,11 +1999,11 @@ NS_IMETHODIMP nsAccessibilityService::AddNativeRootAccessible(void * aAtkAccessi
*aRootAccessible = static_cast<nsIAccessible*>(rootAccWrap);
NS_ADDREF(*aRootAccessible);
nsRefPtr<nsApplicationAccessibleWrap> appRoot =
nsApplicationAccessible *applicationAcc =
nsAccessNode::GetApplicationAccessible();
NS_ENSURE_STATE(appRoot);
NS_ENSURE_STATE(applicationAcc);
appRoot->AddRootAccessible(*aRootAccessible);
applicationAcc->AddRootAccessible(*aRootAccessible);
return NS_OK;
#else
@ -2021,11 +2017,11 @@ NS_IMETHODIMP nsAccessibilityService::RemoveNativeRootAccessible(nsIAccessible *
void* atkAccessible;
aRootAccessible->GetNativeInterface(&atkAccessible);
nsRefPtr<nsApplicationAccessibleWrap> appRoot =
nsApplicationAccessible *applicationAcc =
nsAccessNode::GetApplicationAccessible();
NS_ENSURE_STATE(appRoot);
NS_ENSURE_STATE(applicationAcc);
appRoot->RemoveRootAccessible(aRootAccessible);
applicationAcc->RemoveRootAccessible(aRootAccessible);
return NS_OK;
#else

Просмотреть файл

@ -55,7 +55,8 @@ nsApplicationAccessible::nsApplicationAccessible() :
////////////////////////////////////////////////////////////////////////////////
// nsISupports
NS_IMPL_ISUPPORTS_INHERITED0(nsApplicationAccessible, nsAccessible)
NS_IMPL_ISUPPORTS_INHERITED1(nsApplicationAccessible, nsAccessible,
nsIAccessibleApplication)
////////////////////////////////////////////////////////////////////////////////
// nsIAccessible
@ -124,6 +125,64 @@ nsApplicationAccessible::GetParent(nsIAccessible **aAccessible)
return IsDefunct() ? NS_ERROR_FAILURE : NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// nsIAccessibleApplication
NS_IMETHODIMP
nsApplicationAccessible::GetAppName(nsAString& aName)
{
aName.Truncate();
if (!mAppInfo)
return NS_ERROR_FAILURE;
nsCAutoString cname;
nsresult rv = mAppInfo->GetName(cname);
NS_ENSURE_SUCCESS(rv, rv);
AppendUTF8toUTF16(cname, aName);
return NS_OK;
}
NS_IMETHODIMP
nsApplicationAccessible::GetAppVersion(nsAString& aVersion)
{
aVersion.Truncate();
if (!mAppInfo)
return NS_ERROR_FAILURE;
nsCAutoString cversion;
nsresult rv = mAppInfo->GetVersion(cversion);
NS_ENSURE_SUCCESS(rv, rv);
AppendUTF8toUTF16(cversion, aVersion);
return NS_OK;
}
NS_IMETHODIMP
nsApplicationAccessible::GetPlatformName(nsAString& aName)
{
aName.AssignLiteral("Gecko");
return NS_OK;
}
NS_IMETHODIMP
nsApplicationAccessible::GetPlatformVersion(nsAString& aVersion)
{
aVersion.Truncate();
if (!mAppInfo)
return NS_ERROR_FAILURE;
nsCAutoString cversion;
nsresult rv = mAppInfo->GetPlatformVersion(cversion);
NS_ENSURE_SUCCESS(rv, rv);
AppendUTF8toUTF16(cversion, aVersion);
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// nsAccessNode public methods
@ -136,6 +195,14 @@ nsApplicationAccessible::IsDefunct()
nsresult
nsApplicationAccessible::Init()
{
mAppInfo = do_GetService("@mozilla.org/xre/app-info;1");
return NS_OK;
}
nsresult
nsApplicationAccessible::Shutdown()
{
mAppInfo = nsnull;
return NS_OK;
}

Просмотреть файл

@ -44,7 +44,10 @@
#define __NS_APPLICATION_ACCESSIBLE_H__
#include "nsAccessibleWrap.h"
#include "nsIAccessibleApplication.h"
#include "nsIMutableArray.h"
#include "nsIXULAppInfo.h"
/**
* nsApplicationAccessible is for the whole application of Mozilla.
@ -56,7 +59,8 @@
* the nsApplicationAccessible instance.
*/
class nsApplicationAccessible: public nsAccessibleWrap
class nsApplicationAccessible: public nsAccessibleWrap,
public nsIAccessibleApplication
{
public:
nsApplicationAccessible();
@ -72,9 +76,13 @@ public:
NS_IMETHOD GetParent(nsIAccessible **aAccessible);
// nsIAccessibleApplication
NS_DECL_NSIACCESSIBLEAPPLICATION
// nsAccessNode
virtual PRBool IsDefunct();
virtual nsresult Init();
virtual nsresult Shutdown();
// nsAccessible
virtual nsresult GetRoleInternal(PRUint32 *aRole);
@ -93,6 +101,9 @@ protected:
virtual void CacheChildren();
virtual nsAccessible* GetSiblingAtOffset(PRInt32 aOffset,
nsresult *aError = nsnull);
private:
nsCOMPtr<nsIXULAppInfo> mAppInfo;
};
#endif

Просмотреть файл

@ -940,10 +940,10 @@ void nsRootAccessible::GetTargetNode(nsIDOMEvent *aEvent, nsIDOMNode **aTargetNo
nsresult
nsRootAccessible::Init()
{
nsRefPtr<nsApplicationAccessibleWrap> root = GetApplicationAccessible();
NS_ENSURE_STATE(root);
nsApplicationAccessible *applicationAcc = GetApplicationAccessible();
NS_ENSURE_STATE(applicationAcc);
root->AddRootAccessible(this);
applicationAcc->AddRootAccessible(this);
return nsDocAccessibleWrap::Init();
}
@ -956,10 +956,10 @@ nsRootAccessible::Shutdown()
return NS_OK; // Already shutdown
}
nsRefPtr<nsApplicationAccessibleWrap> root = GetApplicationAccessible();
NS_ENSURE_STATE(root);
nsApplicationAccessible *applicationAcc = GetApplicationAccessible();
NS_ENSURE_STATE(applicationAcc);
root->RemoveRootAccessible(this);
applicationAcc->RemoveRootAccessible(this);
mCurrentARIAMenubar = nsnull;

Просмотреть файл

@ -145,9 +145,11 @@ nsAccessNodeWrap::QueryService(REFGUID guidService, REFIID iid, void** ppv)
// Can get to IAccessibleApplication from any node via QS
if (iid == IID_IAccessibleApplication) {
nsRefPtr<nsApplicationAccessibleWrap> app =
GetApplicationAccessible();
nsresult rv = app->QueryNativeInterface(iid, ppv);
nsApplicationAccessible *applicationAcc = GetApplicationAccessible();
if (!applicationAcc)
return E_NOINTERFACE;
nsresult rv = applicationAcc->QueryNativeInterface(iid, ppv);
return NS_SUCCEEDED(rv) ? S_OK : E_NOINTERFACE;
}

Просмотреть файл

@ -44,12 +44,12 @@
#include "nsServiceManagerUtils.h"
nsIXULAppInfo* nsApplicationAccessibleWrap::sAppInfo = nsnull;
////////////////////////////////////////////////////////////////////////////////
// nsISupports
NS_IMPL_ISUPPORTS_INHERITED0(nsApplicationAccessibleWrap,
nsApplicationAccessible)
////////////////////////////////////////////////////////////////////////////////
// IUnknown
STDMETHODIMP
@ -66,6 +66,7 @@ nsApplicationAccessibleWrap::QueryInterface(REFIID iid, void** ppv)
return nsAccessibleWrap::QueryInterface(iid, ppv);
}
////////////////////////////////////////////////////////////////////////////////
// IAccessibleApplication
STDMETHODIMP
@ -74,18 +75,14 @@ nsApplicationAccessibleWrap::get_appName(BSTR *aName)
__try {
*aName = NULL;
if (!sAppInfo)
return E_FAIL;
nsCAutoString cname;
nsresult rv = sAppInfo->GetName(cname);
nsAutoString name;
nsresult rv = GetAppName(name);
if (NS_FAILED(rv))
return GetHRESULT(rv);
if (cname.IsEmpty())
if (name.IsEmpty())
return S_FALSE;
NS_ConvertUTF8toUTF16 name(cname);
*aName = ::SysAllocStringLen(name.get(), name.Length());
return *aName ? S_OK : E_OUTOFMEMORY;
@ -99,18 +96,14 @@ nsApplicationAccessibleWrap::get_appVersion(BSTR *aVersion)
__try {
*aVersion = NULL;
if (!sAppInfo)
return E_FAIL;
nsCAutoString cversion;
nsresult rv = sAppInfo->GetVersion(cversion);
nsAutoString version;
nsresult rv = GetAppVersion(version);
if (NS_FAILED(rv))
return GetHRESULT(rv);
if (cversion.IsEmpty())
if (version.IsEmpty())
return S_FALSE;
NS_ConvertUTF8toUTF16 version(cversion);
*aVersion = ::SysAllocStringLen(version.get(), version.Length());
return *aVersion ? S_OK : E_OUTOFMEMORY;
@ -122,7 +115,15 @@ STDMETHODIMP
nsApplicationAccessibleWrap::get_toolkitName(BSTR *aName)
{
__try {
*aName = ::SysAllocString(L"Gecko");
nsAutoString name;
nsresult rv = GetPlatformName(name);
if (NS_FAILED(rv))
return GetHRESULT(rv);
if (name.IsEmpty())
return S_FALSE;
*aName = ::SysAllocStringLen(name.get(), name.Length());
return *aName ? S_OK : E_OUTOFMEMORY;
} __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
@ -135,18 +136,14 @@ nsApplicationAccessibleWrap::get_toolkitVersion(BSTR *aVersion)
__try {
*aVersion = NULL;
if (!sAppInfo)
return E_FAIL;
nsCAutoString cversion;
nsresult rv = sAppInfo->GetPlatformVersion(cversion);
nsAutoString version;
nsresult rv = GetPlatformVersion(version);
if (NS_FAILED(rv))
return GetHRESULT(rv);
if (cversion.IsEmpty())
if (version.IsEmpty())
return S_FALSE;
NS_ConvertUTF8toUTF16 version(cversion);
*aVersion = ::SysAllocStringLen(version.get(), version.Length());
return *aVersion ? S_OK : E_OUTOFMEMORY;
@ -154,18 +151,16 @@ __try {
return E_FAIL;
}
// nsApplicationAccessibleWrap
////////////////////////////////////////////////////////////////////////////////
// nsApplicationAccessibleWrap public static
void
nsApplicationAccessibleWrap::PreCreate()
{
nsresult rv = CallGetService("@mozilla.org/xre/app-info;1", &sAppInfo);
NS_ASSERTION(NS_SUCCEEDED(rv), "No XUL application info service");
}
void
nsApplicationAccessibleWrap::Unload()
{
NS_IF_RELEASE(sAppInfo);
}

Просмотреть файл

@ -45,8 +45,6 @@
#include "AccessibleApplication.h"
#include "nsIXULAppInfo.h"
class nsApplicationAccessibleWrap: public nsApplicationAccessible,
public IAccessibleApplication
{
@ -73,9 +71,6 @@ public:
public:
static void PreCreate();
static void Unload();
private:
static nsIXULAppInfo* sAppInfo;
};
#endif

Просмотреть файл

@ -84,6 +84,7 @@ _TEST_FILES =\
test_editabletext_2.html \
test_elm_listbox.xul \
$(warning test_elm_media.html temporarily disabled) \
test_elm_nsApplicationAcc.html \
test_elm_plugin.html \
test_invalidate_accessnode.html \
test_name.html \
@ -91,7 +92,6 @@ _TEST_FILES =\
test_name_button.html \
test_name_link.html \
test_name_markup.html \
test_name_nsApplicationAcc.html \
test_name_nsRootAcc.xul \
$(warning test_nsIAccessible_comboboxes.xul temporarily disabled) \
test_nsIAccessible_selects.html \

Просмотреть файл

@ -22,6 +22,7 @@ const nsIAccessibleCoordinateType =
Components.interfaces.nsIAccessibleCoordinateType;
const nsIAccessibleDocument = Components.interfaces.nsIAccessibleDocument;
const nsIAccessibleApplication = Components.interfaces.nsIAccessibleApplication;
const nsIAccessibleText = Components.interfaces.nsIAccessibleText;
const nsIAccessibleEditableText = Components.interfaces.nsIAccessibleEditableText;
@ -277,7 +278,8 @@ function getRootAccessible(aAccOrElmOrID)
*/
function getApplicationAccessible()
{
return gAccRetrieval.getApplicationAccessible();
return gAccRetrieval.getApplicationAccessible().
QueryInterface(nsIAccessibleApplication);
}
/**

Просмотреть файл

@ -23,6 +23,7 @@
return;
}
// nsIAccessible::name
var bundleServ = Components.classes["@mozilla.org/intl/stringbundle;1"]
.getService(Components.interfaces.nsIStringBundleService);
var bundle = bundleServ.createBundle("chrome://branding/locale/brand.properties");
@ -39,6 +40,16 @@
is (accessible.name, applicationName, "wrong application accessible name");
// nsIAccessibleApplication
var appInfo = Components.classes["@mozilla.org/xre/app-info;1"].
getService(Components.interfaces.nsIXULAppInfo);
is(accessible.appName, appInfo.name, "Wrong application name");
is(accessible.appVersion, appInfo.version, "Wrong application version");
is(accessible.platformName, "Gecko", "Wrong platform name");
is(accessible.platformVersion, appInfo.platformVersion,
"Wrong platform version");
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();