Bug 485270 - embed and object HTML tags should be given an accessible role of embedded object, r=marcoz, davidb

This commit is contained in:
Alexander Surkov 2009-10-15 11:53:08 +08:00
Родитель 85a41b73a7
Коммит 49acc68365
12 изменённых файлов: 147 добавлений и 27 удалений

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

@ -44,7 +44,7 @@
* @note - When adding a new role, be sure to also add it to nsRoleMap.h for
* each platform.
*/
[scriptable, uuid(6793ca5c-c7cb-41db-9fb9-c16c0525f962)]
[scriptable, uuid(f134da65-39a8-4330-843c-5bd42780b34c)]
interface nsIAccessibleRole : nsISupports
{
/**
@ -776,10 +776,15 @@ interface nsIAccessibleRole : nsISupports
*/
const unsigned long ROLE_GRID_CELL = 121;
/**
* Represents an embedded object. It is used for html:object or html:embed.
*/
const unsigned long ROLE_EMBEDDED_OBJECT = 122;
/**
* It's not role actually. This constant is important to help ensure
* nsRoleMap's are synchronized.
*/
const unsigned long ROLE_LAST_ENTRY = 122;
const unsigned long ROLE_LAST_ENTRY = 123;
};

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

@ -168,6 +168,7 @@ static const PRUint32 atkRoleMap[] = {
ATK_ROLE_LIST, // nsIAccessibleRole::ROLE_LISTBOX 119
ATK_ROLE_UNKNOWN, // nsIAccessibleRole::ROLE_FLAT_EQUATION 120
ATK_ROLE_TABLE_CELL, // nsIAccessibleRole::ROLE_GRID_CELL 121
ATK_ROLE_PANEL, // nsIAccessibleRole::ROLE_EMBEDDED_OBJECT 122
kROLE_ATK_LAST_ENTRY // nsIAccessibleRole::ROLE_LAST_ENTRY
};

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

@ -763,15 +763,16 @@ nsAccessibilityService::CreateHTMLObjectFrameAccessible(nsObjectFrame *aFrame,
nsCOMPtr<nsIPluginInstance> pluginInstance ;
aFrame->GetPluginInstance(*getter_AddRefs(pluginInstance));
if (pluginInstance) {
// Note: pluginPort will be null if windowless.
HWND pluginPort = nsnull;
aFrame->GetPluginPort(&pluginPort);
if (pluginPort) {
*aAccessible = new nsHTMLWin32ObjectOwnerAccessible(node, weakShell, pluginPort);
if (*aAccessible) {
NS_ADDREF(*aAccessible);
return NS_OK;
}
}
*aAccessible =
new nsHTMLWin32ObjectOwnerAccessible(node, weakShell, pluginPort);
NS_ENSURE_TRUE(*aAccessible, NS_ERROR_OUT_OF_MEMORY);
NS_ADDREF(*aAccessible);
return NS_OK;
}
#endif

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

@ -289,7 +289,8 @@ static const char kRoleNames[][20] = {
"listbox rich option", //ROLE_RICH_OPTION
"listbox", //ROLE_LISTBOX
"flat equation", //ROLE_FLAT_EQUATION
"gridcell" //ROLE_GRID_CELL
"gridcell", //ROLE_GRID_CELL
"embedded object" //ROLE_EMBEDDED_OBJECT
};
/**

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

@ -164,5 +164,6 @@ static const NSString* AXRoles [] = {
NSAccessibilityListRole, // ROLE_LISTBOX
NSAccessibilityUnknownRole, // ROLE_FLAT_EQUATION
NSAccessibilityGroupRole, // ROLE_GRID_CELL
NSAccessibilityGroupRole // ROLE_EMBEDDED_OBJECT
@"ROLE_LAST_ENTRY" // ROLE_LAST_ENTRY. bogus role that will never be shown (just marks the end of this array)!
};

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

@ -39,13 +39,21 @@
#include "nsHTMLWin32ObjectAccessible.h"
#include "nsAccessibleWrap.h"
////////////////////////////////////////////////////////////////////////////////
// nsHTMLWin32ObjectOwnerAccessible
////////////////////////////////////////////////////////////////////////////////
nsHTMLWin32ObjectOwnerAccessible::nsHTMLWin32ObjectOwnerAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell, void* aHwnd):
nsAccessibleWrap(aNode, aShell)
nsHTMLWin32ObjectOwnerAccessible::
nsHTMLWin32ObjectOwnerAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell,
void* aHwnd) :
nsAccessibleWrap(aNode, aShell)
{
mHwnd = aHwnd;
}
////////////////////////////////////////////////////////////////////////////////
// nsHTMLWin32ObjectOwnerAccessible: nsAccessNode implementation
nsresult
nsHTMLWin32ObjectOwnerAccessible::Shutdown()
{
@ -54,37 +62,83 @@ nsHTMLWin32ObjectOwnerAccessible::Shutdown()
return NS_OK;
}
/**
* Our only child is a nsHTMLWin32ObjectAccessible
*/
NS_IMETHODIMP nsHTMLWin32ObjectOwnerAccessible::GetFirstChild(nsIAccessible **aFirstChild)
////////////////////////////////////////////////////////////////////////////////
// nsHTMLWin32ObjectOwnerAccessible: nsIAccessible implementation
NS_IMETHODIMP
nsHTMLWin32ObjectOwnerAccessible::GetFirstChild(nsIAccessible **aFirstChild)
{
*aFirstChild = mNativeAccessible;
NS_ENSURE_ARG_POINTER(aFirstChild);
*aFirstChild = nsnull;
// Our only child is a nsHTMLWin32ObjectAccessible object.
if (!mNativeAccessible) {
if (!mHwnd) {
if (!mHwnd)
return NS_OK;
}
mNativeAccessible = new nsHTMLWin32ObjectAccessible(mHwnd) ;
mNativeAccessible = new nsHTMLWin32ObjectAccessible(mHwnd);
NS_ENSURE_TRUE(mNativeAccessible, NS_ERROR_OUT_OF_MEMORY);
SetFirstChild(mNativeAccessible);
*aFirstChild = mNativeAccessible;
}
*aFirstChild = mNativeAccessible;
NS_IF_ADDREF(*aFirstChild);
return NS_OK;
}
NS_IMETHODIMP nsHTMLWin32ObjectOwnerAccessible::GetLastChild(nsIAccessible **aLastChild)
NS_IMETHODIMP
nsHTMLWin32ObjectOwnerAccessible::GetLastChild(nsIAccessible **aLastChild)
{
return GetFirstChild(aLastChild);
}
NS_IMETHODIMP nsHTMLWin32ObjectOwnerAccessible::GetChildCount(PRInt32 *aChildCount)
NS_IMETHODIMP
nsHTMLWin32ObjectOwnerAccessible::GetChildCount(PRInt32 *aChildCount)
{
NS_ENSURE_ARG_POINTER(aChildCount);
nsCOMPtr<nsIAccessible> onlyChild;
GetFirstChild(getter_AddRefs(onlyChild));
*aChildCount = onlyChild ? 1 : 0;
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// nsHTMLWin32ObjectOwnerAccessible: nsAccessible implementation
nsresult
nsHTMLWin32ObjectOwnerAccessible::GetRoleInternal(PRUint32 *aRole)
{
NS_ENSURE_ARG_POINTER(aRole);
*aRole = nsIAccessibleRole::ROLE_EMBEDDED_OBJECT;
return NS_OK;
}
nsresult
nsHTMLWin32ObjectOwnerAccessible::GetStateInternal(PRUint32 *aState,
PRUint32 *aExtraState)
{
nsresult rv = nsAccessibleWrap::GetStateInternal(aState, aExtraState);
if (rv == NS_OK_DEFUNCT_OBJECT)
return rv;
// XXX: No HWND means this is windowless plugin which is not accessible in
// the meantime.
if (!mHwnd)
*aState = nsIAccessibleStates::STATE_UNAVAILABLE;
return rv;
}
////////////////////////////////////////////////////////////////////////////////
// nsHTMLWin32ObjectAccessible
////////////////////////////////////////////////////////////////////////////////
nsHTMLWin32ObjectAccessible::nsHTMLWin32ObjectAccessible(void* aHwnd):
nsLeafAccessible(nsnull, nsnull)
{

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

@ -64,6 +64,10 @@ public:
// nsAccessNode
virtual nsresult Shutdown();
// nsAccessible
virtual nsresult GetRoleInternal(PRUint32 *aRole);
virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
protected:
void* mHwnd;
nsCOMPtr<nsIAccessible> mNativeAccessible;

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

@ -440,6 +440,9 @@ static const WindowsRoleMapItem gWindowsRoleMap[] = {
// nsIAccessibleRole::ROLE_GRID_CELL
{ ROLE_SYSTEM_CELL, ROLE_SYSTEM_CELL },
// nsIAccessibleRole::ROLE_EMBEDDED_OBJECT
{ USE_ROLE_STRING, IA2_ROLE_EMBEDDED_OBJECT },
// nsIAccessibleRole::ROLE_LAST_ENTRY
{ ROLE_WINDOWS_LAST_ENTRY, ROLE_WINDOWS_LAST_ENTRY }
};

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

@ -89,6 +89,7 @@ _TEST_FILES =\
test_elm_filectrl.html \
test_elm_listbox.xul \
$(warning test_elm_media.html temporarily disabled) \
test_elm_plugin.html \
test_elm_tree.xul \
test_elm_txtcntnr.html \
test_events_caretmove.html \

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

@ -12,6 +12,7 @@ const ROLE_COMBOBOX_LIST = nsIAccessibleRole.ROLE_COMBOBOX_LIST;
const ROLE_COMBOBOX_OPTION = nsIAccessibleRole.ROLE_COMBOBOX_OPTION;
const ROLE_COLUMNHEADER = nsIAccessibleRole.ROLE_COLUMNHEADER;
const ROLE_DOCUMENT = nsIAccessibleRole.ROLE_DOCUMENT;
const ROLE_EMBEDDED_OBJECT = nsIAccessibleRole.ROLE_EMBEDDED_OBJECT;
const ROLE_ENTRY = nsIAccessibleRole.ROLE_ENTRY;
const ROLE_FLAT_EQUATION = nsIAccessibleRole.ROLE_FLAT_EQUATION;
const ROLE_FORM = nsIAccessibleRole.ROLE_FORM;

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

@ -94,10 +94,12 @@ function testStates(aAccOrElmOrID, aState, aExtraState, aAbsentState,
}
// unavailable
if ((state & STATE_UNAVAILABLE)
&& (getRole(aAccOrElmOrID) != ROLE_GROUPING))
isState(state & STATE_FOCUSABLE, STATE_FOCUSABLE, false,
"Disabled " + id + " must be focusable!");
if (state & STATE_UNAVAILABLE) {
var role = getRole(aAccOrElmOrID);
if (role != ROLE_GROUPING && role != ROLE_EMBEDDED_OBJECT)
isState(state & STATE_FOCUSABLE, STATE_FOCUSABLE, false,
"Disabled " + id + " must be focusable!");
}
}
/**

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

@ -0,0 +1,46 @@
<!DOCTYPE html>
<html>
<head>
<title>Plugin tests</title>
<link rel="stylesheet" type="text/css"
href="chrome://mochikit/content/tests/SimpleTest/test.css" />
<script type="application/javascript"
src="chrome://mochikit/content/MochiKit/packed.js"></script>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript"
src="chrome://mochikit/content/a11y/accessible/common.js"></script>
<script type="application/javascript"
src="chrome://mochikit/content/a11y/accessible/role.js"></script>
<script type="application/javascript"
src="chrome://mochikit/content/a11y/accessible/states.js"></script>
<script type="application/javascript">
function doTest()
{
testRole("plugin", ROLE_EMBEDDED_OBJECT);
testStates("plugin", STATE_UNAVAILABLE);
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
addA11yLoadEvent(doTest);
</script>
</head>
<body>
<a target="_blank"
title="embed and object HTML tags should be given an accessible role of embedded object"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=485270">Mozilla Bug 485270</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
</pre>
<embed id="plugin" type="application/x-test" width="300" height="300"></embed>
</body>
</html>