Bug 485270 - embed and object HTML tags should be given an accessible role of embedded object, r=marcoz, davidb
This commit is contained in:
Родитель
85a41b73a7
Коммит
49acc68365
|
@ -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>
|
Загрузка…
Ссылка в новой задаче