Bug 483573 - Expose HTML5 video and audio elements' embedded controls through accessibility APIs, r=davidb, r=MarcoZ, sr=roc

This commit is contained in:
Alexander Surkov 2009-04-20 09:09:21 +02:00
Родитель 4fae5b8b3c
Коммит c4b0c0a555
9 изменённых файлов: 205 добавлений и 15 удалений

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

@ -46,7 +46,7 @@ interface nsObjectFrame;
interface nsIContent;
interface nsITimer;
[uuid(44685af8-18be-494a-8e64-16c7d4296dd1)]
[uuid(05481634-4700-45d6-8a0c-704f3a5abc00)]
interface nsIAccessibilityService : nsIAccessibleRetrieval
{
nsIAccessible createOuterDocAccessible(in nsIDOMNode aNode);
@ -66,6 +66,7 @@ interface nsIAccessibilityService : nsIAccessibleRetrieval
nsIAccessible createHTMLImageAccessible(in nsIFrame aFrame);
nsIAccessible createHTMLLabelAccessible(in nsIFrame aFrame);
nsIAccessible createHTMLListboxAccessible(in nsIDOMNode aNode, in nsIWeakReference aPresShell);
nsIAccessible createHTMLMediaAccessible(in nsIFrame aFrame);
nsIAccessible createHTMLObjectFrameAccessible(in nsObjectFrame aFrame);
nsIAccessible createHTMLRadioButtonAccessible(in nsIFrame aFrame);
nsIAccessible createHTMLSelectOptionAccessible(in nsIDOMNode aNode, in nsIAccessible aAccParent, in nsIWeakReference aPresShell);

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

@ -684,6 +684,27 @@ nsAccessibilityService::CreateHTMLListboxAccessible(nsIDOMNode* aDOMNode, nsIWea
return NS_OK;
}
NS_IMETHODIMP
nsAccessibilityService::CreateHTMLMediaAccessible(nsIFrame *aFrame,
nsIAccessible **aAccessible)
{
NS_ENSURE_ARG_POINTER(aAccessible);
*aAccessible = nsnull;
nsCOMPtr<nsIDOMNode> node;
nsCOMPtr<nsIWeakReference> weakShell;
nsresult rv = GetInfo(aFrame, getter_AddRefs(weakShell),
getter_AddRefs(node));
NS_ENSURE_SUCCESS(rv, rv);
*aAccessible = new nsEnumRoleAccessible(node, weakShell,
nsIAccessibleRole::ROLE_GROUPING);
NS_ENSURE_TRUE(*aAccessible, NS_ERROR_OUT_OF_MEMORY);
NS_ADDREF(*aAccessible);
return NS_OK;
}
/**
* We can have several cases here.
* 1) a text or html embedded document where the contentDocument

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

@ -37,8 +37,11 @@
* ***** END LICENSE BLOCK ***** */
#include "nsAccessibleTreeWalker.h"
#include "nsAccessibilityAtoms.h"
#include "nsAccessNode.h"
#include "nsIAnonymousContentCreator.h"
#include "nsIServiceManager.h"
#include "nsIContent.h"
#include "nsIDOMXULElement.h"
@ -229,9 +232,17 @@ void nsAccessibleTreeWalker::UpdateFrame(PRBool aTryFirstChild)
if (!mState.frame) {
return;
}
if (aTryFirstChild) {
nsIContent *containerContent = mState.frame->GetContent();
// If the frame implements nsIAnonymousContentCreator interface then go down
// through the frames and obtain anonymous nodes for them.
nsIAnonymousContentCreator* creator = do_QueryFrame(mState.frame);
mState.frame = mState.frame->GetFirstChild(nsnull);
if (creator && mState.frame && mState.siblingIndex < 0) {
mState.domNode = do_QueryInterface(mState.frame->GetContent());
mState.siblingIndex = eSiblingsWalkFrames;
}
// temporary workaround for Bug 359210. We never want to walk frames.
// Aaron Leventhal will refix :before and :after content later without walking frames.
#if 0
@ -254,17 +265,6 @@ void nsAccessibleTreeWalker::UpdateFrame(PRBool aTryFirstChild)
mState.siblingIndex = eSiblingsWalkFrames;
}
#endif
// Special case: <input type="file">
// We should still need to walk frames inside the file control frame
// This special case may turn into a more general rule after Firefox 3,
// if HTML 5 controls use nsIAnonymousContentCreator
if (containerContent->Tag() == nsAccessibilityAtoms::input &&
containerContent->AttrValueIs(kNameSpaceID_None, nsAccessibilityAtoms::type,
NS_LITERAL_STRING("file"), eIgnoreCase) &&
mState.frame && mState.siblingIndex < 0) {
mState.domNode = do_QueryInterface(mState.frame->GetContent());
mState.siblingIndex = eSiblingsWalkFrames;
}
}
else {
mState.frame = mState.frame->GetNextSibling();

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

@ -48,6 +48,7 @@ include $(topsrcdir)/config/rules.mk
_TEST_FILES =\
letters.gif \
moz.png \
$(topsrcdir)/content/media/video/test/bug461281.ogg \
longdesc_src.html \
attributes.js \
common.js \
@ -74,6 +75,8 @@ _TEST_FILES =\
test_bug420863.html \
$(warning test_childAtPoint.xul temporarily disabled) \
test_cssattrs.html \
test_elm_filectrl.html \
test_elm_media.html \
test_events_caretmove.html \
test_events_mutation.html \
test_events_tree.xul \

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

@ -265,6 +265,38 @@ function ensureAccessibleTree(aAccOrElmOrID)
}
}
/**
* Compare expected and actual accessibles trees.
*/
function testAccessibleTree(aAccOrElmOrID, aAccTree)
{
var acc = getAccessible(aAccOrElmOrID);
if (!acc)
return;
for (var prop in aAccTree) {
var msg = "Wrong value of property '" + prop + "'.";
if (prop == "role")
is(roleToString(acc[prop]), roleToString(aAccTree[prop]), msg);
else if (prop != "children")
is(acc[prop], aAccTree[prop], msg);
}
if ("children" in aAccTree) {
var children = acc.children;
is(aAccTree.children.length, children.length,
"Different amount of expected children.");
if (aAccTree.children.length == children.length) {
for (var i = 0; i < children.length; i++) {
var child = children.queryElementAt(i, nsIAccessible);
testAccessibleTree(child, aAccTree.children[i]);
}
}
}
}
/**
* Convert role to human readable string.
*/

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

@ -2,7 +2,6 @@
// Role constants
const ROLE_ALERT = nsIAccessibleRole.ROLE_ALERT;
const ROLE_PUSHBUTTON = nsIAccessibleRole.ROLE_PUSHBUTTON;
const ROLE_CELL = nsIAccessibleRole.ROLE_CELL;
const ROLE_CHROME_WINDOW = nsIAccessibleRole.ROLE_CHROME_WINDOW;
const ROLE_COMBOBOX = nsIAccessibleRole.ROLE_COMBOBOX;
@ -26,7 +25,10 @@ const ROLE_NOTHING = nsIAccessibleRole.ROLE_NOTHING;
const ROLE_OPTION = nsIAccessibleRole.ROLE_OPTION;
const ROLE_PARAGRAPH = nsIAccessibleRole.ROLE_PARAGRAPH;
const ROLE_PASSWORD_TEXT = nsIAccessibleRole.ROLE_PASSWORD_TEXT;
const ROLE_PROGRESSBAR = nsIAccessibleRole.ROLE_PROGRESSBAR;
const ROLE_PUSHBUTTON = nsIAccessibleRole.ROLE_PUSHBUTTON;
const ROLE_SECTION = nsIAccessibleRole.ROLE_SECTION;
const ROLE_SLIDER = nsIAccessibleRole.ROLE_SLIDER;
const ROLE_TABLE = nsIAccessibleRole.ROLE_TABLE;
const ROLE_TEXT_CONTAINER = nsIAccessibleRole.ROLE_TEXT_CONTAINER;
const ROLE_TEXT_LEAF = nsIAccessibleRole.ROLE_TEXT_LEAF;

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

@ -0,0 +1,55 @@
<!DOCTYPE html>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=483573
-->
<head>
<title>File Input Control 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">
function doTest()
{
var accTree = {
role: ROLE_TEXT_CONTAINER,
children: [
{
role: ROLE_ENTRY
},
{
role: ROLE_PUSHBUTTON
}
]
};
testAccessibleTree("filectrl", accTree);
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
addLoadEvent(doTest);
</script>
</head>
<body>
<a target="_blank"
title="Expose HTML5 video and audio elements' embedded controls through accessibility APIs"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=483573">Mozilla Bug 483573</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
</pre>
<input type="file" id="filectrl" />
</body>
</html>

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

@ -0,0 +1,65 @@
<!DOCTYPE html>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=483573
-->
<head>
<title>HTML5 audio/video 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">
function doTest()
{
var accTree = {
role: ROLE_GROUPING,
children: [
{ // start/stop button
role: ROLE_PUSHBUTTON
},
{ // buffer bar
role: ROLE_PROGRESSBAR
},
{ // progress bar
role: ROLE_PROGRESSBAR
},
{ // slider of progress bar
role: ROLE_SLIDER
},
{ // volume button
role: ROLE_PUSHBUTTON
}
]
};
testAccessibleTree("audio", accTree);
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
addLoadEvent(doTest);
</script>
</head>
<body>
<a target="_blank"
title="Expose HTML5 video and audio elements' embedded controls through accessibility APIs"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=483573">Mozilla Bug 483573</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
</pre>
<audio id="audio" src="chrome://mochikit/content/a11y/accessible/bug461281.ogg"
autoplay="true" controls="true">
</body>
</html>

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

@ -56,6 +56,12 @@
#include "nsBoxLayoutState.h"
#include "nsBoxFrame.h"
#ifdef ACCESSIBILITY
#include "nsIServiceManager.h"
#include "nsIAccessible.h"
#include "nsIAccessibilityService.h"
#endif
nsIFrame*
NS_NewHTMLVideoFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
{
@ -249,7 +255,12 @@ nsVideoFrame::GetType() const
NS_IMETHODIMP
nsVideoFrame::GetAccessible(nsIAccessible** aAccessible)
{
return NS_ERROR_FAILURE;
nsCOMPtr<nsIAccessibilityService> accService =
do_GetService("@mozilla.org/accessibilityService;1");
NS_ENSURE_STATE(accService);
return accService->CreateHTMLMediaAccessible(static_cast<nsIFrame*>(this),
aAccessible);
}
#endif