зеркало из https://github.com/mozilla/pjs.git
Bug 468418 - Expose level for nested lists in HTML, r=marcoz, aaronlev
This commit is contained in:
Родитель
9714de8cfa
Коммит
5e4bb7fd66
|
@ -2015,95 +2015,12 @@ nsAccessible::GetAttributes(nsIPersistentProperties **aAttributes)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Level/setsize/posinset
|
// Group attributes (level/setsize/posinset)
|
||||||
if (!nsAccUtils::HasAccGroupAttrs(attributes)) {
|
if (!nsAccUtils::HasAccGroupAttrs(attributes)) {
|
||||||
// The role of an accessible can be pointed by ARIA attribute but ARIA
|
// Calculate group attributes based on accessible hierarhy if they weren't
|
||||||
// posinset, level, setsize may be skipped. Therefore we calculate here
|
// provided by ARIA or by accessible class implementation.
|
||||||
// these properties to map them into description.
|
rv = ComputeGroupAttributes(role, attributes);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
// If accessible is invisible we don't want to calculate group ARIA
|
|
||||||
// attributes for it.
|
|
||||||
if ((role == nsIAccessibleRole::ROLE_LISTITEM ||
|
|
||||||
role == nsIAccessibleRole::ROLE_MENUITEM ||
|
|
||||||
role == nsIAccessibleRole::ROLE_CHECK_MENU_ITEM ||
|
|
||||||
role == nsIAccessibleRole::ROLE_RADIO_MENU_ITEM ||
|
|
||||||
role == nsIAccessibleRole::ROLE_RADIOBUTTON ||
|
|
||||||
role == nsIAccessibleRole::ROLE_PAGETAB ||
|
|
||||||
role == nsIAccessibleRole::ROLE_OPTION ||
|
|
||||||
role == nsIAccessibleRole::ROLE_RADIOBUTTON ||
|
|
||||||
role == nsIAccessibleRole::ROLE_OUTLINEITEM) &&
|
|
||||||
0 == (nsAccUtils::State(this) & nsIAccessibleStates::STATE_INVISIBLE)) {
|
|
||||||
|
|
||||||
PRUint32 baseRole = role;
|
|
||||||
if (role == nsIAccessibleRole::ROLE_CHECK_MENU_ITEM ||
|
|
||||||
role == nsIAccessibleRole::ROLE_RADIO_MENU_ITEM)
|
|
||||||
baseRole = nsIAccessibleRole::ROLE_MENUITEM;
|
|
||||||
|
|
||||||
nsCOMPtr<nsIAccessible> parent = GetParent();
|
|
||||||
NS_ENSURE_TRUE(parent, NS_ERROR_FAILURE);
|
|
||||||
|
|
||||||
PRInt32 positionInGroup = 0;
|
|
||||||
PRInt32 setSize = 0;
|
|
||||||
|
|
||||||
nsCOMPtr<nsIAccessible> sibling, nextSibling;
|
|
||||||
parent->GetFirstChild(getter_AddRefs(sibling));
|
|
||||||
NS_ENSURE_TRUE(sibling, NS_ERROR_FAILURE);
|
|
||||||
|
|
||||||
PRBool foundCurrent = PR_FALSE;
|
|
||||||
PRUint32 siblingRole, siblingBaseRole;
|
|
||||||
while (sibling) {
|
|
||||||
sibling->GetFinalRole(&siblingRole);
|
|
||||||
|
|
||||||
siblingBaseRole = siblingRole;
|
|
||||||
if (siblingRole == nsIAccessibleRole::ROLE_CHECK_MENU_ITEM ||
|
|
||||||
siblingRole == nsIAccessibleRole::ROLE_RADIO_MENU_ITEM)
|
|
||||||
siblingBaseRole = nsIAccessibleRole::ROLE_MENUITEM;
|
|
||||||
|
|
||||||
// If sibling is visible and has the same base role.
|
|
||||||
if (siblingBaseRole == baseRole &&
|
|
||||||
!(nsAccUtils::State(sibling) & nsIAccessibleStates::STATE_INVISIBLE)) {
|
|
||||||
++ setSize;
|
|
||||||
if (!foundCurrent) {
|
|
||||||
++ positionInGroup;
|
|
||||||
if (sibling == this)
|
|
||||||
foundCurrent = PR_TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the sibling is separator
|
|
||||||
if (siblingRole == nsIAccessibleRole::ROLE_SEPARATOR) {
|
|
||||||
if (foundCurrent) // the our group is ended
|
|
||||||
break;
|
|
||||||
|
|
||||||
// not our group, continue the searching
|
|
||||||
positionInGroup = 0;
|
|
||||||
setSize = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
sibling->GetNextSibling(getter_AddRefs(nextSibling));
|
|
||||||
sibling = nextSibling;
|
|
||||||
}
|
|
||||||
|
|
||||||
PRInt32 groupLevel = 0;
|
|
||||||
if (role == nsIAccessibleRole::ROLE_OUTLINEITEM) {
|
|
||||||
groupLevel = 1;
|
|
||||||
nsCOMPtr<nsIAccessible> nextParent;
|
|
||||||
while (parent) {
|
|
||||||
parent->GetFinalRole(&role);
|
|
||||||
|
|
||||||
if (role == nsIAccessibleRole::ROLE_OUTLINE)
|
|
||||||
break;
|
|
||||||
if (role == nsIAccessibleRole::ROLE_GROUPING)
|
|
||||||
++ groupLevel;
|
|
||||||
|
|
||||||
parent->GetParent(getter_AddRefs(nextParent));
|
|
||||||
parent.swap(nextParent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nsAccUtils::SetAccGroupAttrs(attributes, groupLevel, positionInGroup,
|
|
||||||
setSize);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Expose all ARIA attributes
|
// Expose all ARIA attributes
|
||||||
|
@ -3567,3 +3484,145 @@ nsAccessible::GetActionRule(PRUint32 aStates)
|
||||||
|
|
||||||
return eNoAction;
|
return eNoAction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsAccessible::ComputeGroupAttributes(PRUint32 aRole,
|
||||||
|
nsIPersistentProperties *aAttributes)
|
||||||
|
{
|
||||||
|
// The role of an accessible can be specified by ARIA attribute but ARIA
|
||||||
|
// posinset, level, setsize may be skipped. As well this method is used
|
||||||
|
// for non ARIA accessibles to avoid GetAccessibleInternal() method
|
||||||
|
// implementation in subclasses. For example, it's being used to calculate
|
||||||
|
// group attributes for HTML li elements.
|
||||||
|
|
||||||
|
// If accessible is invisible we don't want to calculate group attributes for
|
||||||
|
// it.
|
||||||
|
if (nsAccUtils::State(this) & nsIAccessibleStates::STATE_INVISIBLE)
|
||||||
|
return NS_OK;
|
||||||
|
|
||||||
|
if (aRole != nsIAccessibleRole::ROLE_LISTITEM &&
|
||||||
|
aRole != nsIAccessibleRole::ROLE_MENUITEM &&
|
||||||
|
aRole != nsIAccessibleRole::ROLE_CHECK_MENU_ITEM &&
|
||||||
|
aRole != nsIAccessibleRole::ROLE_RADIO_MENU_ITEM &&
|
||||||
|
aRole != nsIAccessibleRole::ROLE_RADIOBUTTON &&
|
||||||
|
aRole != nsIAccessibleRole::ROLE_PAGETAB &&
|
||||||
|
aRole != nsIAccessibleRole::ROLE_OPTION &&
|
||||||
|
aRole != nsIAccessibleRole::ROLE_OUTLINEITEM)
|
||||||
|
return NS_OK;
|
||||||
|
|
||||||
|
PRUint32 baseRole = aRole;
|
||||||
|
if (aRole == nsIAccessibleRole::ROLE_CHECK_MENU_ITEM ||
|
||||||
|
aRole == nsIAccessibleRole::ROLE_RADIO_MENU_ITEM)
|
||||||
|
baseRole = nsIAccessibleRole::ROLE_MENUITEM;
|
||||||
|
|
||||||
|
nsCOMPtr<nsIAccessible> parent = GetParent();
|
||||||
|
NS_ENSURE_TRUE(parent, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
|
// Compute 'posinset' and 'setsize' attributes.
|
||||||
|
PRInt32 positionInGroup = 0;
|
||||||
|
PRInt32 setSize = 0;
|
||||||
|
|
||||||
|
nsCOMPtr<nsIAccessible> sibling, nextSibling;
|
||||||
|
parent->GetFirstChild(getter_AddRefs(sibling));
|
||||||
|
NS_ENSURE_STATE(sibling);
|
||||||
|
|
||||||
|
PRBool foundCurrent = PR_FALSE;
|
||||||
|
PRUint32 siblingRole, siblingBaseRole;
|
||||||
|
while (sibling) {
|
||||||
|
siblingRole = nsAccUtils::Role(sibling);
|
||||||
|
|
||||||
|
siblingBaseRole = siblingRole;
|
||||||
|
if (siblingRole == nsIAccessibleRole::ROLE_CHECK_MENU_ITEM ||
|
||||||
|
siblingRole == nsIAccessibleRole::ROLE_RADIO_MENU_ITEM)
|
||||||
|
siblingBaseRole = nsIAccessibleRole::ROLE_MENUITEM;
|
||||||
|
|
||||||
|
// If sibling is visible and has the same base role.
|
||||||
|
if (siblingBaseRole == baseRole &&
|
||||||
|
!(nsAccUtils::State(sibling) & nsIAccessibleStates::STATE_INVISIBLE)) {
|
||||||
|
++ setSize;
|
||||||
|
if (!foundCurrent) {
|
||||||
|
++ positionInGroup;
|
||||||
|
if (sibling == this)
|
||||||
|
foundCurrent = PR_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the sibling is separator
|
||||||
|
if (siblingRole == nsIAccessibleRole::ROLE_SEPARATOR) {
|
||||||
|
if (foundCurrent) // the our group is ended
|
||||||
|
break;
|
||||||
|
|
||||||
|
// not our group, continue the searching
|
||||||
|
positionInGroup = 0;
|
||||||
|
setSize = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
sibling->GetNextSibling(getter_AddRefs(nextSibling));
|
||||||
|
sibling = nextSibling;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute 'level' attribute.
|
||||||
|
PRInt32 groupLevel = 0;
|
||||||
|
if (aRole == nsIAccessibleRole::ROLE_OUTLINEITEM) {
|
||||||
|
// Always expose 'level' attribute for 'outlineitem' accessible. The number
|
||||||
|
// of nested 'grouping' accessibles containing 'outlineitem' accessible is
|
||||||
|
// its level.
|
||||||
|
groupLevel = 1;
|
||||||
|
nsCOMPtr<nsIAccessible> nextParent;
|
||||||
|
while (parent) {
|
||||||
|
PRUint32 parentRole = nsAccUtils::Role(parent);
|
||||||
|
|
||||||
|
if (parentRole == nsIAccessibleRole::ROLE_OUTLINE)
|
||||||
|
break;
|
||||||
|
if (parentRole == nsIAccessibleRole::ROLE_GROUPING)
|
||||||
|
++ groupLevel;
|
||||||
|
|
||||||
|
parent->GetParent(getter_AddRefs(nextParent));
|
||||||
|
parent.swap(nextParent);
|
||||||
|
}
|
||||||
|
} else if (aRole == nsIAccessibleRole::ROLE_LISTITEM) {
|
||||||
|
// Expose 'level' attribute on nested lists. We assume nested list is a last
|
||||||
|
// child of listitem of parent list. We don't handle the case when nested
|
||||||
|
// lists have more complex structure, for example when there are accessibles
|
||||||
|
// between parent listitem and nested list.
|
||||||
|
|
||||||
|
// Calculate 'level' attribute based on number of parent listitems.
|
||||||
|
nsCOMPtr<nsIAccessible> nextParent;
|
||||||
|
while (parent) {
|
||||||
|
PRUint32 parentRole = nsAccUtils::Role(parent);
|
||||||
|
|
||||||
|
if (parentRole == nsIAccessibleRole::ROLE_LISTITEM)
|
||||||
|
++ groupLevel;
|
||||||
|
else if (parentRole != nsIAccessibleRole::ROLE_LIST)
|
||||||
|
break;
|
||||||
|
|
||||||
|
parent->GetParent(getter_AddRefs(nextParent));
|
||||||
|
parent.swap(nextParent);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (groupLevel == 0) {
|
||||||
|
// If this listitem is on top of nested lists then expose 'level'
|
||||||
|
// attribute.
|
||||||
|
nsCOMPtr<nsIAccessible> parent = GetParent();
|
||||||
|
parent->GetFirstChild(getter_AddRefs(sibling));
|
||||||
|
|
||||||
|
while (sibling) {
|
||||||
|
nsCOMPtr<nsIAccessible> siblingChild;
|
||||||
|
sibling->GetLastChild(getter_AddRefs(siblingChild));
|
||||||
|
if (nsAccUtils::Role(siblingChild) == nsIAccessibleRole::ROLE_LIST) {
|
||||||
|
groupLevel = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
sibling->GetNextSibling(getter_AddRefs(nextSibling));
|
||||||
|
sibling.swap(nextSibling);
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
groupLevel++; // level is 1-index based
|
||||||
|
}
|
||||||
|
|
||||||
|
nsAccUtils::SetAccGroupAttrs(aAttributes, groupLevel, positionInGroup,
|
||||||
|
setSize);
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
|
@ -284,6 +284,17 @@ protected:
|
||||||
*/
|
*/
|
||||||
PRUint32 GetActionRule(PRUint32 aStates);
|
PRUint32 GetActionRule(PRUint32 aStates);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute group attributes ('posinset', 'setsize' and 'level') based
|
||||||
|
* on accessible hierarchy. Used by GetAttributes() method if group attributes
|
||||||
|
* weren't provided by ARIA or by internal accessible implementation.
|
||||||
|
*
|
||||||
|
* @param aRole [in] role of this accessible
|
||||||
|
* @param aAttributes [in, out] object attributes
|
||||||
|
*/
|
||||||
|
nsresult ComputeGroupAttributes(PRUint32 aRole,
|
||||||
|
nsIPersistentProperties *aAttributes);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fires platform accessible event. It's notification method only. It does
|
* Fires platform accessible event. It's notification method only. It does
|
||||||
* change nothing on Gecko side. Mostly you should use
|
* change nothing on Gecko side. Mostly you should use
|
||||||
|
|
|
@ -64,7 +64,8 @@ _TEST_FILES =\
|
||||||
test_bug420863.html \
|
test_bug420863.html \
|
||||||
test_cssattrs.html \
|
test_cssattrs.html \
|
||||||
test_events_caretmove.html \
|
test_events_caretmove.html \
|
||||||
$(warning test_groupattrs.xul temporarily disabled) \
|
test_groupattrs.xul \
|
||||||
|
test_groupattrs.html \
|
||||||
$(warning test_table_indexes.html temporarily disabled) \
|
$(warning test_table_indexes.html temporarily disabled) \
|
||||||
test_nsIAccessible_actions.html \
|
test_nsIAccessible_actions.html \
|
||||||
$(warning test_nsIAccessible_actions.xul temporarily disabled) \
|
$(warning test_nsIAccessible_actions.xul temporarily disabled) \
|
||||||
|
|
|
@ -4,15 +4,15 @@
|
||||||
/**
|
/**
|
||||||
* Test object attributes.
|
* Test object attributes.
|
||||||
*
|
*
|
||||||
* @param aID [in] the ID of DOM element having accessible
|
* @param aAccOrElmOrID [in] the ID, DOM node or accessible
|
||||||
* @param aAttrs [in] the map of expected object attributes
|
* @param aAttrs [in] the map of expected object attributes
|
||||||
* (name/value pairs)
|
* (name/value pairs)
|
||||||
* @param aSkipUnexpectedAttrs [in] points this function doesn't fail if
|
* @param aSkipUnexpectedAttrs [in] points this function doesn't fail if
|
||||||
* unexpected attribute is encountered
|
* unexpected attribute is encountered
|
||||||
*/
|
*/
|
||||||
function testAttrs(aID, aAttrs, aSkipUnexpectedAttrs)
|
function testAttrs(aAccOrElmOrID, aAttrs, aSkipUnexpectedAttrs)
|
||||||
{
|
{
|
||||||
var accessible = getAccessible(aID);
|
var accessible = getAccessible(aAccOrElmOrID);
|
||||||
if (!accessible)
|
if (!accessible)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -22,14 +22,35 @@ function testAttrs(aID, aAttrs, aSkipUnexpectedAttrs)
|
||||||
} catch (e) { }
|
} catch (e) { }
|
||||||
|
|
||||||
if (!attrs) {
|
if (!attrs) {
|
||||||
ok(false, "Can't get object attributes for " + aID);
|
ok(false, "Can't get object attributes for " + aAccOrElmOrID);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var errorMsg = " for " + aID;
|
var errorMsg = " for " + aAccOrElmOrID;
|
||||||
compareAttrs(errorMsg, attrs, aAttrs, aSkipUnexpectedAttrs);
|
compareAttrs(errorMsg, attrs, aAttrs, aSkipUnexpectedAttrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test group object attributes (posinset, setsize and level)
|
||||||
|
*
|
||||||
|
* @param aAccOrElmOrID [in] the ID, DOM node or accessible
|
||||||
|
* @param aPosInSet [in] the value of 'posinset' attribute
|
||||||
|
* @param aSetSize [in] the value of 'setsize' attribute
|
||||||
|
* @param aLevel [in, optional] the value of 'level' attribute
|
||||||
|
*/
|
||||||
|
function testGroupAttrs(aAccOrElmOrID, aPosInSet, aSetSize, aLevel)
|
||||||
|
{
|
||||||
|
var attrs = {
|
||||||
|
"posinset": String(aPosInSet),
|
||||||
|
"setsize": String(aSetSize)
|
||||||
|
};
|
||||||
|
|
||||||
|
if (aLevel)
|
||||||
|
attrs["level"] = String(aLevel);
|
||||||
|
|
||||||
|
testAttrs(aAccOrElmOrID, attrs, true);
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// Text attributes.
|
// Text attributes.
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,120 @@
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<title>Group attributes 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/attributes.js"></script>
|
||||||
|
|
||||||
|
<script type="application/javascript">
|
||||||
|
function doTest()
|
||||||
|
{
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
// HTML select
|
||||||
|
testGroupAttrs("opt1", 1, 2);
|
||||||
|
testGroupAttrs("opt2", 2, 2);
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
// HTML ul/ol
|
||||||
|
testGroupAttrs("li1", 1, 3);
|
||||||
|
testGroupAttrs("li2", 2, 3);
|
||||||
|
testGroupAttrs("li3", 3, 3);
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
// HTML ul/ol (nested lists)
|
||||||
|
|
||||||
|
testGroupAttrs("li4", 1, 3, 1);
|
||||||
|
testGroupAttrs("li5", 2, 3, 1);
|
||||||
|
testGroupAttrs("li6", 3, 3, 1);
|
||||||
|
|
||||||
|
testGroupAttrs("n_li4", 1, 3, 2);
|
||||||
|
testGroupAttrs("n_li5", 2, 3, 2);
|
||||||
|
testGroupAttrs("n_li6", 3, 3, 2);
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
// ARIA list
|
||||||
|
testGroupAttrs("li7", 1, 3);
|
||||||
|
testGroupAttrs("li8", 2, 3);
|
||||||
|
testGroupAttrs("li9", 3, 3);
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
// ARIA list (nested lists)
|
||||||
|
testGroupAttrs("li10", 1, 3, 1);
|
||||||
|
testGroupAttrs("li11", 2, 3, 1);
|
||||||
|
testGroupAttrs("li12", 3, 3, 1);
|
||||||
|
|
||||||
|
testGroupAttrs("n_li10", 1, 3, 2);
|
||||||
|
testGroupAttrs("n_li11", 2, 3, 2);
|
||||||
|
testGroupAttrs("n_li12", 3, 3, 2);
|
||||||
|
|
||||||
|
SimpleTest.finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
SimpleTest.waitForExplicitFinish();
|
||||||
|
addLoadEvent(doTest);
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<a target="_blank"
|
||||||
|
href="https://bugzilla.mozilla.org/show_bug.cgi?id=468418"
|
||||||
|
title="Expose level for nested lists in HTML">
|
||||||
|
Mozilla Bug 468418
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<p id="display"></p>
|
||||||
|
<div id="content" style="display: none"></div>
|
||||||
|
<pre id="test">
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<select size="4">
|
||||||
|
<option id="opt1">option1</option>
|
||||||
|
<option id="opt2">option2</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li id="li1">Oranges</li>
|
||||||
|
<li id="li2">Apples</li>
|
||||||
|
<li id="li3">Bananas</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<ol>
|
||||||
|
<li id="li4">Oranges</li>
|
||||||
|
<li id="li5">Apples</li>
|
||||||
|
<li id="li6">Bananas
|
||||||
|
<ul>
|
||||||
|
<li id="n_li4">Oranges</li>
|
||||||
|
<li id="n_li5">Apples</li>
|
||||||
|
<li id="n_li6">Bananas</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
<span role="list">
|
||||||
|
<span role="listitem" id="li7">Oranges</span>
|
||||||
|
<span role="listitem" id="li8">Apples</span>
|
||||||
|
<span role="listitem" id="li9">Bananas</span>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<span role="list">
|
||||||
|
<span role="listitem" id="li10">Oranges</span>
|
||||||
|
<span role="listitem" id="li11">Apples</span>
|
||||||
|
<span role="listitem" id="li12">Bananas
|
||||||
|
<span role="list">
|
||||||
|
<span role="listitem" id="n_li10">Oranges</span>
|
||||||
|
<span role="listitem" id="n_li11">Apples</span>
|
||||||
|
<span role="listitem" id="n_li12">Bananas</span>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -18,19 +18,6 @@
|
||||||
|
|
||||||
<script type="application/javascript">
|
<script type="application/javascript">
|
||||||
<![CDATA[
|
<![CDATA[
|
||||||
function testGroupAttrs(aID, aPosInSet, aSetSize, aLevel)
|
|
||||||
{
|
|
||||||
var attrs = {
|
|
||||||
"posinset": aPosInSet,
|
|
||||||
"setsize": aSetSize
|
|
||||||
};
|
|
||||||
|
|
||||||
if (aLevel)
|
|
||||||
attrs["level"] = aLevel;
|
|
||||||
|
|
||||||
testAttrs(aID, attrs, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
function doTest()
|
function doTest()
|
||||||
{
|
{
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -40,26 +27,24 @@
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
// xul:menu (bug 443881)
|
// xul:menu (bug 443881)
|
||||||
if (navigator.platform == "Win32") {
|
var menu1 = document.getElementById("menu_item1");
|
||||||
var menu1 = document.getElementById("menu_item1");
|
menu1.open = true;
|
||||||
menu1.open = true;
|
|
||||||
|
window.setTimeout(function() {
|
||||||
window.setTimeout(function() {
|
var menu2 = document.getElementById("menu_item2");
|
||||||
var menu2 = document.getElementById("menu_item2");
|
menu2.open = true;
|
||||||
menu2.open = true;
|
|
||||||
|
window.setTimeout(function() {
|
||||||
window.setTimeout(function() {
|
testGroupAttrs("menu_item1.1", "1", "1");
|
||||||
testGroupAttrs("menu_item1.1", "1", "1");
|
testGroupAttrs("menu_item1.2", "1", "3");
|
||||||
testGroupAttrs("menu_item1.2", "1", "3");
|
testGroupAttrs("menu_item1.4", "2", "3");
|
||||||
testGroupAttrs("menu_item1.4", "2", "3");
|
testGroupAttrs("menu_item2", "3", "3");
|
||||||
testGroupAttrs("menu_item2", "3", "3");
|
testGroupAttrs("menu_item2.1", "1", "2", "1");
|
||||||
testGroupAttrs("menu_item2.1", "1", "2", "1");
|
testGroupAttrs("menu_item2.2", "2", "2", "1");
|
||||||
testGroupAttrs("menu_item2.2", "2", "2", "1");
|
|
||||||
|
SimpleTest.finish();
|
||||||
SimpleTest.finish();
|
}, 200);
|
||||||
}, 0);
|
}, 200);
|
||||||
}, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
// ARIA menu (bug 441888)
|
// ARIA menu (bug 441888)
|
||||||
|
@ -67,9 +52,6 @@
|
||||||
testGroupAttrs("aria-menuitemcheckbox", "2", "3");
|
testGroupAttrs("aria-menuitemcheckbox", "2", "3");
|
||||||
testGroupAttrs("aria-menuitemradio", "3", "3");
|
testGroupAttrs("aria-menuitemradio", "3", "3");
|
||||||
testGroupAttrs("aria-menuitem2", "1", "1");
|
testGroupAttrs("aria-menuitem2", "1", "1");
|
||||||
if (navigator.platform != "Win32")
|
|
||||||
SimpleTest.finish();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SimpleTest.waitForExplicitFinish();
|
SimpleTest.waitForExplicitFinish();
|
||||||
|
|
Загрузка…
Ссылка в новой задаче