зеркало из https://github.com/mozilla/pjs.git
Bug 483573 - Expose HTML5 video and audio elements' embedded controls through accessibility APIs, r=davidb, r=MarcoZ, sr=roc
This commit is contained in:
Родитель
4fae5b8b3c
Коммит
c4b0c0a555
|
@ -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
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче