Bug 658272 - Implement figure and figcaption accessibility, r=tbsaunde, marcoz

--HG--
rename : accessible/tests/mochitest/test_elm_landmarks.html => accessible/tests/mochitest/elm/test_landmarks.html
rename : accessible/tests/mochitest/test_elm_listbox.xul => accessible/tests/mochitest/elm/test_listbox.xul
rename : accessible/tests/mochitest/test_elm_nsApplicationAcc.html => accessible/tests/mochitest/elm/test_nsApplicationAcc.html
rename : accessible/tests/mochitest/test_elm_plugin.html => accessible/tests/mochitest/elm/test_plugin.html
This commit is contained in:
Alexander Surkov 2011-12-05 14:04:06 +08:00
parent 018e8c959d
commit 18093eb539
16 changed files with 294 additions and 18 deletions

View File

@ -787,10 +787,15 @@ interface nsIAccessibleRole : nsISupports
*/
const unsigned long ROLE_NOTE = 123;
/**
* A figure. Used for things like HTML5 figure element.
*/
const unsigned long ROLE_FIGURE = 124;
/**
* It's not role actually. This constant is important to help ensure
* nsRoleMap's are synchronized.
*/
const unsigned long ROLE_LAST_ENTRY = 124;
const unsigned long ROLE_LAST_ENTRY = 125;
};

View File

@ -169,6 +169,7 @@ static const PRUint32 atkRoleMap[] = {
ATK_ROLE_TABLE_CELL, // nsIAccessibleRole::ROLE_GRID_CELL 121
ATK_ROLE_PANEL, // nsIAccessibleRole::ROLE_EMBEDDED_OBJECT 122
ATK_ROLE_SECTION, // nsIAccessibleRole::ROLE_NOTE 123
ATK_ROLE_PANEL, // nsIAccessibleRole::ROLE_FIGURE 124
kROLE_ATK_LAST_ENTRY // nsIAccessibleRole::ROLE_LAST_ENTRY
};

View File

@ -1605,7 +1605,20 @@ nsAccessibilityService::CreateHTMLAccessibleByMarkup(nsIFrame* aFrame,
nsIWeakReference* aWeakShell)
{
// This method assumes we're in an HTML namespace.
nsIAtom *tag = aContent->Tag();
nsIAtom* tag = aContent->Tag();
if (tag == nsGkAtoms::figcaption) {
nsAccessible* accessible =
new nsHTMLFigcaptionAccessible(aContent, aWeakShell);
NS_IF_ADDREF(accessible);
return accessible;
}
if (tag == nsGkAtoms::figure) {
nsAccessible* accessible = new nsHTMLFigureAccessible(aContent, aWeakShell);
NS_IF_ADDREF(accessible);
return accessible;
}
if (tag == nsGkAtoms::legend) {
nsAccessible* accessible = new nsHTMLLegendAccessible(aContent, aWeakShell);
NS_IF_ADDREF(accessible);

View File

@ -424,7 +424,8 @@ static const char kRoleNames[][20] = {
"flat equation", //ROLE_FLAT_EQUATION
"gridcell", //ROLE_GRID_CELL
"embedded object", //ROLE_EMBEDDED_OBJECT
"note" //ROLE_NOTE
"note", //ROLE_NOTE
"figure" //ROLE_FIGURE
};
/**

View File

@ -793,3 +793,106 @@ nsHTMLLegendAccessible::NativeRole()
{
return nsIAccessibleRole::ROLE_LABEL;
}
////////////////////////////////////////////////////////////////////////////////
// nsHTMLFigureAccessible
////////////////////////////////////////////////////////////////////////////////
nsHTMLFigureAccessible::
nsHTMLFigureAccessible(nsIContent* aContent, nsIWeakReference* aShell) :
nsHyperTextAccessibleWrap(aContent, aShell)
{
}
nsresult
nsHTMLFigureAccessible::GetAttributesInternal(nsIPersistentProperties* aAttributes)
{
nsresult rv = nsHyperTextAccessibleWrap::GetAttributesInternal(aAttributes);
NS_ENSURE_SUCCESS(rv, rv);
// Expose figure xml-role.
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::xmlroles,
NS_LITERAL_STRING("figure"));
return NS_OK;
}
PRUint32
nsHTMLFigureAccessible::NativeRole()
{
return nsIAccessibleRole::ROLE_FIGURE;
}
nsresult
nsHTMLFigureAccessible::GetNameInternal(nsAString& aName)
{
nsresult rv = nsHyperTextAccessibleWrap::GetNameInternal(aName);
NS_ENSURE_SUCCESS(rv, rv);
if (!aName.IsEmpty())
return NS_OK;
nsIContent* captionContent = Caption();
if (captionContent) {
return nsTextEquivUtils::
AppendTextEquivFromContent(this, captionContent, &aName);
}
return NS_OK;
}
Relation
nsHTMLFigureAccessible::RelationByType(PRUint32 aType)
{
Relation rel = nsHyperTextAccessibleWrap::RelationByType(aType);
if (aType == nsIAccessibleRelation::RELATION_LABELLED_BY)
rel.AppendTarget(Caption());
return rel;
}
nsIContent*
nsHTMLFigureAccessible::Caption() const
{
for (nsIContent* childContent = mContent->GetFirstChild(); childContent;
childContent = childContent->GetNextSibling()) {
if (childContent->NodeInfo()->Equals(nsGkAtoms::figcaption,
mContent->GetNameSpaceID())) {
return childContent;
}
}
return nsnull;
}
////////////////////////////////////////////////////////////////////////////////
// nsHTMLFigcaptionAccessible
////////////////////////////////////////////////////////////////////////////////
nsHTMLFigcaptionAccessible::
nsHTMLFigcaptionAccessible(nsIContent* aContent, nsIWeakReference* aShell) :
nsHyperTextAccessibleWrap(aContent, aShell)
{
}
PRUint32
nsHTMLFigcaptionAccessible::NativeRole()
{
return nsIAccessibleRole::ROLE_CAPTION;
}
Relation
nsHTMLFigcaptionAccessible::RelationByType(PRUint32 aType)
{
Relation rel = nsHyperTextAccessibleWrap::RelationByType(aType);
if (aType != nsIAccessibleRelation::RELATION_LABEL_FOR)
return rel;
nsAccessible* figure = Parent();
if (figure &&
figure->GetContent()->NodeInfo()->Equals(nsGkAtoms::figure,
mContent->GetNameSpaceID())) {
rel.AppendTarget(figure);
}
return rel;
}

View File

@ -228,4 +228,36 @@ public:
virtual Relation RelationByType(PRUint32 aType);
};
#endif
/**
* Accessible for HTML5 figure element.
*/
class nsHTMLFigureAccessible : public nsHyperTextAccessibleWrap
{
public:
nsHTMLFigureAccessible(nsIContent* aContent, nsIWeakReference* aShell);
// nsAccessible
virtual nsresult GetAttributesInternal(nsIPersistentProperties* aAttributes);
virtual nsresult GetNameInternal(nsAString& aName);
virtual PRUint32 NativeRole();
virtual Relation RelationByType(PRUint32 aType);
protected:
nsIContent* Caption() const;
};
/**
* Accessible for HTML5 figcaption element.
*/
class nsHTMLFigcaptionAccessible : public nsHyperTextAccessibleWrap
{
public:
nsHTMLFigcaptionAccessible(nsIContent* aContent, nsIWeakReference* aShell);
// nsAccessible
virtual PRUint32 NativeRole();
virtual Relation RelationByType(PRUint32 aType);
};
#endif

View File

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

View File

@ -446,6 +446,9 @@ static const WindowsRoleMapItem gWindowsRoleMap[] = {
// nsIAccessibleRole::ROLE_NOTE
{ USE_ROLE_STRING, IA2_ROLE_NOTE },
// nsIAccessibleRole::ROLE_FIGURE
{ ROLE_SYSTEM_GROUPING, ROLE_SYSTEM_GROUPING },
// nsIAccessibleRole::ROLE_LAST_ENTRY
{ ROLE_WINDOWS_LAST_ENTRY, ROLE_WINDOWS_LAST_ENTRY }
};

View File

@ -46,6 +46,7 @@ DIRS = \
actions \
attributes \
editabletext \
elm \
events \
focus \
hyperlink \
@ -94,10 +95,6 @@ _TEST_FILES =\
test_childAtPoint.html \
test_childAtPoint.xul \
test_descr.html \
test_elm_landmarks.html \
test_elm_listbox.xul \
test_elm_nsApplicationAcc.html \
test_elm_plugin.html \
test_nsIAccessibleDocument.html \
test_nsIAccessibleImage.html \
test_nsIAccessNode_utils.html \

View File

@ -0,0 +1,57 @@
#
# ***** 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) 2009
# 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 of 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 *****
DEPTH = ../../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
relativesrcdir = accessible/elm
include $(DEPTH)/config/autoconf.mk
include $(topsrcdir)/config/rules.mk
_TEST_FILES =\
test_figure.html \
test_landmarks.html \
test_listbox.xul \
test_nsApplicationAcc.html \
test_plugin.html \
$(NULL)
libs:: $(_TEST_FILES)
$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/a11y/$(relativesrcdir)

View File

@ -0,0 +1,62 @@
<!DOCTYPE html>
<html>
<head>
<title>HTML5 figure/figcaption tests</title>
<link rel="stylesheet" type="text/css"
href="chrome://mochikit/content/tests/SimpleTest/test.css" />
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript"
src="../common.js"></script>
<script type="application/javascript"
src="../role.js"></script>
<script type="application/javascript"
src="../attributes.js"></script>
<script type="application/javascript"
src="../relations.js"></script>
<script type="application/javascript"
src="../name.js"></script>
<script type="application/javascript">
function doTest()
{
testRole("figure", ROLE_FIGURE);
testRole("figcaption", ROLE_CAPTION);
todo(false, "figure name gets extra whitespace in the end!");
testName("figure", "figure caption ");
testName("figcaption", null);
testRelation("figure", RELATION_LABELLED_BY, "figcaption");
testRelation("figcaption", RELATION_LABEL_FOR, "figure");
testAttrs("figure", {"xml-roles" : "figure"}, true);
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
addA11yLoadEvent(doTest);
</script>
</head>
<body>
<a target="_blank"
title="Implement figure and figcaption accessibility"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=658272">
Mozilla Bug 658272
</a><br/>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
</pre>
<figure id="figure">
<figcaption id="figcaption">figure caption</figcaption>
</figure>
</body>
</html>

View File

@ -9,11 +9,11 @@
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript"
src="common.js"></script>
src="../common.js"></script>
<script type="application/javascript"
src="role.js"></script>
src="../role.js"></script>
<script type="application/javascript"
src="attributes.js"></script>
src="../attributes.js"></script>
<script type="application/javascript">

View File

@ -10,9 +10,9 @@
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
<script type="application/javascript"
src="common.js"></script>
src="../common.js"></script>
<script type="application/javascript"
src="role.js"></script>
src="../role.js"></script>
<script type="application/javascript">
<![CDATA[

View File

@ -8,9 +8,9 @@
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript"
src="common.js"></script>
src="../common.js"></script>
<script type="application/javascript"
src="role.js"></script>
src="../role.js"></script>
<script type="application/javascript">
function doTest()

View File

@ -9,11 +9,11 @@
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript"
src="common.js"></script>
src="../common.js"></script>
<script type="application/javascript"
src="role.js"></script>
src="../role.js"></script>
<script type="application/javascript"
src="states.js"></script>
src="../states.js"></script>
<script type="application/javascript">

View File

@ -20,6 +20,7 @@ const ROLE_DIALOG = nsIAccessibleRole.ROLE_DIALOG;
const ROLE_DOCUMENT = nsIAccessibleRole.ROLE_DOCUMENT;
const ROLE_EMBEDDED_OBJECT = nsIAccessibleRole.ROLE_EMBEDDED_OBJECT;
const ROLE_ENTRY = nsIAccessibleRole.ROLE_ENTRY;
const ROLE_FIGURE = nsIAccessibleRole.ROLE_FIGURE;
const ROLE_FOOTER = nsIAccessibleRole.ROLE_FOOTER;
const ROLE_FLAT_EQUATION = nsIAccessibleRole.ROLE_FLAT_EQUATION;
const ROLE_FORM = nsIAccessibleRole.ROLE_FORM;