mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 666212 - summary attribute content mapped to accessible name in MSAA, r=marcoz
This commit is contained in:
parent
1c939adf6e
commit
04a98c120f
@ -519,7 +519,7 @@ PRUint32 nsTextEquivUtils::gRoleToNameRulesMap[] =
|
||||
eNoRule, // ROLE_AUTOCOMPLETE
|
||||
eNoRule, // ROLE_EDITBAR
|
||||
eFromValue, // ROLE_ENTRY
|
||||
eNoRule, // ROLE_CAPTION
|
||||
eFromSubtreeIfRec, // ROLE_CAPTION
|
||||
eNoRule, // ROLE_DOCUMENT_FRAME
|
||||
eFromSubtreeIfRec, // ROLE_HEADING
|
||||
eNoRule, // ROLE_PAGE
|
||||
|
@ -464,10 +464,22 @@ nsresult
|
||||
nsHTMLTableAccessible::GetNameInternal(nsAString& aName)
|
||||
{
|
||||
nsAccessible::GetNameInternal(aName);
|
||||
if (!aName.IsEmpty())
|
||||
return NS_OK;
|
||||
|
||||
if (aName.IsEmpty())
|
||||
mContent->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::summary, aName);
|
||||
// Use table caption as a name.
|
||||
nsAccessible* caption = Caption();
|
||||
if (caption) {
|
||||
nsIContent* captionContent = caption->GetContent();
|
||||
if (captionContent) {
|
||||
nsTextEquivUtils::AppendTextEquivFromContent(this, captionContent, &aName);
|
||||
if (!aName.IsEmpty())
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// If no caption then use summary as a name.
|
||||
mContent->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::summary, aName);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -499,11 +511,8 @@ nsHTMLTableAccessible::GetRelationByType(PRUint32 aRelationType,
|
||||
aRelation);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (aRelationType == nsIAccessibleRelation::RELATION_DESCRIBED_BY) {
|
||||
nsCOMPtr<nsIAccessible> accCaption;
|
||||
GetCaption(getter_AddRefs(accCaption));
|
||||
return nsRelUtils::AddTarget(aRelationType, aRelation, accCaption);
|
||||
}
|
||||
if (aRelationType == nsIAccessibleRelation::RELATION_DESCRIBED_BY)
|
||||
return nsRelUtils::AddTarget(aRelationType, aRelation, Caption());
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -514,10 +523,9 @@ nsHTMLTableAccessible::GetRelationByType(PRUint32 aRelationType,
|
||||
NS_IMETHODIMP
|
||||
nsHTMLTableAccessible::GetCaption(nsIAccessible **aCaption)
|
||||
{
|
||||
nsAccessible* firstChild = GetChildAt(0);
|
||||
if (firstChild && firstChild->Role() == nsIAccessibleRole::ROLE_CAPTION)
|
||||
NS_ADDREF(*aCaption = firstChild);
|
||||
NS_ENSURE_ARG_POINTER(aCaption);
|
||||
|
||||
NS_IF_ADDREF(*aCaption = Caption());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -1268,17 +1276,23 @@ nsHTMLTableAccessible::Description(nsString& aDescription)
|
||||
if (!aDescription.IsEmpty())
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsIAccessible> captionAccessible;
|
||||
GetCaption(getter_AddRefs(captionAccessible));
|
||||
nsCOMPtr<nsIAccessNode> captionAccessNode = do_QueryInterface(captionAccessible);
|
||||
if (captionAccessNode) {
|
||||
nsCOMPtr<nsIDOMNode> captionNode;
|
||||
captionAccessNode->GetDOMNode(getter_AddRefs(captionNode));
|
||||
nsCOMPtr<nsIContent> captionContent = do_QueryInterface(captionNode);
|
||||
if (captionContent)
|
||||
// Use summary as description if it weren't used as a name.
|
||||
// XXX: get rid code duplication with NameInternal().
|
||||
nsAccessible* caption = Caption();
|
||||
if (caption) {
|
||||
nsIContent* captionContent = caption->GetContent();
|
||||
if (captionContent) {
|
||||
nsAutoString captionText;
|
||||
nsTextEquivUtils::AppendTextEquivFromContent(this, captionContent,
|
||||
&aDescription);
|
||||
&captionText);
|
||||
|
||||
if (!captionText.IsEmpty()) { // summary isn't used as a name.
|
||||
mContent->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::summary,
|
||||
aDescription);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef SHOW_LAYOUT_HEURISTIC
|
||||
if (aDescription.IsEmpty()) {
|
||||
PRBool isProbablyForLayout;
|
||||
|
@ -141,6 +141,14 @@ public:
|
||||
virtual PRUint64 NativeState();
|
||||
virtual nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
|
||||
|
||||
// TableAccessible
|
||||
inline nsAccessible* Caption() const
|
||||
{
|
||||
nsAccessible* child = mChildren.SafeElementAt(0, nsnull);
|
||||
return child && child->Role() == nsIAccessibleRole::ROLE_CAPTION ?
|
||||
child : nsnull;
|
||||
}
|
||||
|
||||
// nsHTMLTableAccessible
|
||||
|
||||
/**
|
||||
|
@ -7,7 +7,6 @@ var gRuleDoc = null;
|
||||
|
||||
// Debuggin stuff.
|
||||
var gDumpToConsole = false;
|
||||
gA11yEventDumpToConsole = gDumpToConsole;
|
||||
|
||||
/**
|
||||
* Start name tests. Run through markup elements and test names for test
|
||||
@ -149,7 +148,7 @@ function testNameForRule(aElm, aRuleElm)
|
||||
|
||||
testNameForAttrRule(aElm, aRuleElm);
|
||||
|
||||
} else if (aRuleElm.hasAttribute("elm") && aRuleElm.hasAttribute("elmattr")) {
|
||||
} else if (aRuleElm.hasAttribute("elm")) {
|
||||
if (gDumpToConsole) {
|
||||
dump("\nProcessing rule { elm: " + aRuleElm.getAttribute("elm") +
|
||||
", elmattr: " + aRuleElm.getAttribute("elmattr") +" }\n");
|
||||
@ -178,7 +177,7 @@ function testNameForAttrRule(aElm, aRule)
|
||||
if (type == "string") {
|
||||
name = attrValue;
|
||||
|
||||
} else if (type == "ref") {
|
||||
} else if (type == "ref" && attrValue) {
|
||||
var ids = attrValue.split(/\s+/);
|
||||
for (var idx = 0; idx < ids.length; idx++) {
|
||||
var labelElm = getNode(ids[idx]);
|
||||
@ -197,37 +196,53 @@ function testNameForAttrRule(aElm, aRule)
|
||||
}
|
||||
|
||||
function testNameForElmRule(aElm, aRule)
|
||||
{
|
||||
var elm = aRule.getAttribute("elm");
|
||||
var elmattr = aRule.getAttribute("elmattr");
|
||||
{
|
||||
var labelElm;
|
||||
|
||||
var filter = {
|
||||
acceptNode: function filter_acceptNode(aNode)
|
||||
{
|
||||
if (aNode.localName == this.mLocalName &&
|
||||
aNode.getAttribute(this.mAttrName) == this.mAttrValue)
|
||||
return NodeFilter.FILTER_ACCEPT;
|
||||
var tagname = aRule.getAttribute("elm");
|
||||
var attrname = aRule.getAttribute("elmattr");
|
||||
if (attrname) {
|
||||
var filter = {
|
||||
acceptNode: function filter_acceptNode(aNode)
|
||||
{
|
||||
if (aNode.localName == this.mLocalName &&
|
||||
aNode.getAttribute(this.mAttrName) == this.mAttrValue)
|
||||
return NodeFilter.FILTER_ACCEPT;
|
||||
|
||||
return NodeFilter.FILTER_SKIP;
|
||||
},
|
||||
return NodeFilter.FILTER_SKIP;
|
||||
},
|
||||
|
||||
mLocalName: elm,
|
||||
mAttrName: elmattr,
|
||||
mAttrValue: aElm.getAttribute("id")
|
||||
};
|
||||
mLocalName: tagname,
|
||||
mAttrName: attrname,
|
||||
mAttrValue: aElm.getAttribute("id")
|
||||
};
|
||||
|
||||
var treeWalker = document.createTreeWalker(document.body,
|
||||
NodeFilter.SHOW_ELEMENT,
|
||||
filter, false);
|
||||
var labelElm = treeWalker.nextNode();
|
||||
var msg = "Element '" + elm + "' test.";
|
||||
var treeWalker = document.createTreeWalker(document.body,
|
||||
NodeFilter.SHOW_ELEMENT,
|
||||
filter, false);
|
||||
labelElm = treeWalker.nextNode();
|
||||
|
||||
} else {
|
||||
// if attrname is empty then look for the element in subtree.
|
||||
labelElm = aElm.getElementsByTagName(tagname)[0];
|
||||
if (!labelElm)
|
||||
labelElm = aElm.getElementsByTagName("html:" + tagname)[0];
|
||||
}
|
||||
|
||||
if (!labelElm) {
|
||||
ok(false, msg + " Failed to find '" + tagname + "' element.");
|
||||
gTestIterator.iterateNext();
|
||||
return;
|
||||
}
|
||||
|
||||
var msg = "Element '" + tagname + "' test.";
|
||||
testName(aElm, labelElm.getAttribute("a11yname"), msg);
|
||||
|
||||
var parentNode = labelElm.parentNode;
|
||||
|
||||
if (gDumpToConsole) {
|
||||
dump("\nProcessed elm rule. Wait for reorder event on " +
|
||||
prettyName(parentNode) + "'\n");
|
||||
prettyName(parentNode) + "\n");
|
||||
}
|
||||
waitForEvent(EVENT_REORDER, parentNode,
|
||||
gTestIterator.iterateNext, gTestIterator);
|
||||
|
@ -1,31 +1,50 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<!--
|
||||
This XML file is used to create sequence of accessible name tests. It consist of
|
||||
two sections. The first section 'ruledfn' declares name computation rules.
|
||||
The second section 'rulesample' defines markup samples we need to check name
|
||||
computation rules for.
|
||||
This XML file is used to create sequence of accessible name tests. It consist
|
||||
of two sections. The first section 'ruledfn' declares name computation rules.
|
||||
The second section 'rulesample' defines markup samples we need to check name
|
||||
computation rules for.
|
||||
|
||||
Section 'ruledfn' consist of 'ruleset' elements. Every 'ruleset' element is
|
||||
<ruledfn>
|
||||
<ruleset>
|
||||
<rule>
|
||||
|
||||
Section 'ruledfn' contains 'ruleset' elements. Every 'ruleset' element is
|
||||
presented by 'rule' elements so that sequence of 'rule' elements gives the
|
||||
sequence of name computations rules. Every 'rule' element can be one of four
|
||||
types.
|
||||
* name is equal to the value of attribute presented on the element. Example,
|
||||
'aria-label' attribute. In this case 'rule' element has 'attr' attribute
|
||||
pointing to attribute name and 'type' attribute with 'string' value. For
|
||||
example, <rule attr="aria-label" type="string"/>.
|
||||
* name is calculated from elements that are pointed to by attribute value on
|
||||
the element. Example is 'aria-labelledby'. In this case 'rule' element
|
||||
has 'attr' attribute holding the sequence of IDs of elements used to
|
||||
compute the name, in addition the 'rule' element has 'type' attribute with
|
||||
'ref' value. For example, <rule attr="aria-labelledby" type="ref"/>.
|
||||
* name is calculated from another element. Example, html:label@for element.
|
||||
In this case 'rule' element has 'elm' and 'elmattr' attributes. These
|
||||
attributes are used to find an element by tagname and attribute with value
|
||||
equaled to ID of the element. For example, <rule elm="label" elmattr="for"/>.
|
||||
* name is computed from subtree. Example, html:button. In this case 'rule'
|
||||
element has 'fromsubtree' attribute with 'true' value. For example,
|
||||
<rule fromsubtree="true"/>
|
||||
|
||||
* <rule attr='' type='string'/> used when name is equal to the value of
|
||||
attribute presented on the element.
|
||||
|
||||
Example, 'aria-label' attribute. In this case 'rule' element has 'attr'
|
||||
attribute pointing to attribute name and 'type' attribute with 'string'
|
||||
value. For example, <rule attr="aria-label" type="string"/>.
|
||||
|
||||
* <rule attr='' type='ref'/> used when name is calculated from elements that
|
||||
are pointed to by attribute value on the element.
|
||||
|
||||
Example is 'aria-labelledby'. In this case 'rule' element has 'attr'
|
||||
attribute holding the sequence of IDs of elements used to compute the name,
|
||||
in addition the 'rule' element has 'type' attribute with 'ref' value.
|
||||
For example, <rule attr="aria-labelledby" type="ref"/>.
|
||||
|
||||
* <rule elm='' elmattr=''/> used when name is calculated from another
|
||||
element. These attributes are used to find an element by tagname and
|
||||
attribute with value equaled to ID of the element. If 'elmattr' is missed
|
||||
then element from subtree with the given tagname is used.
|
||||
|
||||
Example, html:label@for element, <rule elm="label" elmattr="for"/>.
|
||||
Example, html:caption element, <rule elm="caption"/>
|
||||
|
||||
* <rule fromsubtree='true'/> used when name is computed from subtree.
|
||||
|
||||
Example, html:button. In this case 'rule' element has 'fromsubtree'
|
||||
attribute with 'true' value.
|
||||
|
||||
<rulesample>
|
||||
<markup ruleset=''>
|
||||
|
||||
Section 'rulesample' provides set of markup samples ('markup' elements). Every
|
||||
'markup' element contains an element that accessible name will be computed for
|
||||
@ -120,6 +139,12 @@
|
||||
<rule attr="title" type="string"/>
|
||||
</ruleset>
|
||||
|
||||
<ruleset id="htmltable">
|
||||
<ruleset ref="htmlelm_start"/>
|
||||
<rule elm="caption"/>
|
||||
<rule attr="summary" type="string"/>
|
||||
<ruleset ref="htmlelm_end"/>
|
||||
</ruleset>
|
||||
</ruledfn>
|
||||
|
||||
<rulesample>
|
||||
@ -210,6 +235,25 @@
|
||||
</html:table>
|
||||
</markup>
|
||||
|
||||
<markup ref="html:table" ruleset="htmltable"
|
||||
id="markup6test">
|
||||
<html:span id="l1" a11yname="lby_tst6_1">lby_tst6_1</html:span>
|
||||
<html:span id="l2" a11yname="lby_tst6_2">lby_tst6_2</html:span>
|
||||
<html:label for="t" a11yname="label_tst6">label_tst6</html:label>
|
||||
<!-- layout frame are recreated due to varous reasons, here's text frame
|
||||
placed after caption frame triggres table frame recreation when
|
||||
caption element is removed from DOM; get rid text node after caption
|
||||
node to make the test working -->
|
||||
<html:table id="t" aria-label="arialabel_tst6"
|
||||
aria-labelledby="l1 l2"
|
||||
summary="summary_tst6"
|
||||
title="title_tst6">
|
||||
<html:caption a11yname="caption_tst6">caption_tst6</html:caption><html:tr>
|
||||
<html:td>cell1</html:td>
|
||||
<html:td>cell2</html:td>
|
||||
</html:tr>
|
||||
</html:table>
|
||||
</markup>
|
||||
</rulesample>
|
||||
|
||||
</rules>
|
||||
|
@ -21,6 +21,8 @@
|
||||
|
||||
<script type="application/javascript">
|
||||
// gA11yEventDumpID = "eventdump";
|
||||
//gDumpToConsole = true;
|
||||
//gA11yEventDumpToConsole = true;
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(testNames);
|
||||
@ -35,6 +37,12 @@
|
||||
title="nsIAccessible::name calculation for elements">
|
||||
Mozilla Bug 459635
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=666212"
|
||||
title="summary attribute content mapped to accessible name in MSAA">
|
||||
Mozilla Bug 666212
|
||||
</a>
|
||||
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
|
@ -38,6 +38,15 @@
|
||||
// Description from content of h2.
|
||||
testDescr("p", "heading");
|
||||
|
||||
// From table summary (caption is used as a name)
|
||||
testDescr("table1", "summary");
|
||||
|
||||
// Empty (summary is used as a name)
|
||||
testDescr("table2", "");
|
||||
|
||||
// From title (summary is used as a name)
|
||||
testDescr("table3", "title");
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
@ -54,6 +63,11 @@
|
||||
title="@title attribute no longer exposed on accDescription">
|
||||
Mozilla Bug 489944
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=666212"
|
||||
title="summary attribute content mapped to accessible name in MSAA">
|
||||
Mozilla Bug 666212
|
||||
</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
@ -66,5 +80,18 @@
|
||||
|
||||
<h2 id="heading">heading</h2>
|
||||
<p id="p" aria-describedby="heading" role="button">click me</p>
|
||||
|
||||
<table id="table1" summary="summary">
|
||||
<caption>caption</caption>
|
||||
<tr><td>cell</td></tr>
|
||||
</table>
|
||||
|
||||
<table id="table2" summary="summary">
|
||||
<tr><td>cell</td></tr>
|
||||
</table>
|
||||
|
||||
<table id="table3" summary="summary" title="title">
|
||||
<tr><td>cell</td></tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
|
Loading…
Reference in New Issue
Block a user