зеркало из https://github.com/mozilla/gecko-dev.git
Bug 637578 - Expose explict-name object attribute, r=tbsaunde
This commit is contained in:
Родитель
be6a87d61e
Коммит
fda87aeeef
|
@ -32,7 +32,7 @@ nsTextEquivUtils::GetNameFromSubtree(Accessible* aAccessible,
|
|||
return NS_OK;
|
||||
|
||||
gInitiatorAcc = aAccessible;
|
||||
if (GetRoleRule(aAccessible->Role()) == eFromSubtree) {
|
||||
if (IsNameFromSubtreeAllowed(aAccessible)) {
|
||||
//XXX: is it necessary to care the accessible is not a document?
|
||||
if (aAccessible->IsContent()) {
|
||||
nsAutoString name;
|
||||
|
|
|
@ -89,6 +89,14 @@ public:
|
|||
static nsresult AppendTextEquivFromTextContent(nsIContent *aContent,
|
||||
nsAString *aString);
|
||||
|
||||
/**
|
||||
* Return true if the given accessible allows name from subtree.
|
||||
*/
|
||||
static bool IsNameFromSubtreeAllowed(Accessible* aAccessible)
|
||||
{
|
||||
return GetRoleRule(aAccessible->Role()) == eFromSubtree;
|
||||
}
|
||||
|
||||
private:
|
||||
/**
|
||||
* Iterates accessible children and calculates text equivalent from each
|
||||
|
|
|
@ -275,7 +275,7 @@ Accessible::Name(nsString& aName)
|
|||
|
||||
ENameValueFlag nameFlag = NativeName(aName);
|
||||
if (!aName.IsEmpty())
|
||||
return eNameOK;
|
||||
return nameFlag;
|
||||
|
||||
// In the end get the name from tooltip.
|
||||
if (mContent->IsHTML()) {
|
||||
|
@ -288,14 +288,12 @@ Accessible::Name(nsString& aName)
|
|||
aName.CompressWhitespace();
|
||||
return eNameFromTooltip;
|
||||
}
|
||||
} else {
|
||||
return eNameOK;
|
||||
}
|
||||
|
||||
if (nameFlag != eNoNameOnPurpose)
|
||||
aName.SetIsVoid(true);
|
||||
|
||||
return eNameOK;
|
||||
return nameFlag;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -1055,7 +1053,7 @@ Accessible::TakeFocus()
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
ENameValueFlag
|
||||
Accessible::GetHTMLName(nsString& aLabel)
|
||||
{
|
||||
Accessible* labelAcc = nullptr;
|
||||
|
@ -1066,8 +1064,11 @@ Accessible::GetHTMLName(nsString& aLabel)
|
|||
aLabel.CompressWhitespace();
|
||||
}
|
||||
|
||||
if (aLabel.IsEmpty())
|
||||
nsTextEquivUtils::GetNameFromSubtree(this, aLabel);
|
||||
if (!aLabel.IsEmpty())
|
||||
return eNameOK;
|
||||
|
||||
nsTextEquivUtils::GetNameFromSubtree(this, aLabel);
|
||||
return aLabel.IsEmpty() ? eNameOK : eNameFromSubtree;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1082,7 +1083,7 @@ Accessible::GetHTMLName(nsString& aLabel)
|
|||
* the control that uses the control="controlID" syntax will use
|
||||
* the child label for its Name.
|
||||
*/
|
||||
void
|
||||
ENameValueFlag
|
||||
Accessible::GetXULName(nsString& aName)
|
||||
{
|
||||
// CASE #1 (via label attribute) -- great majority of the cases
|
||||
|
@ -1125,10 +1126,9 @@ Accessible::GetXULName(nsString& aName)
|
|||
}
|
||||
}
|
||||
|
||||
// XXX If CompressWhiteSpace worked on nsAString we could avoid a copy
|
||||
aName.CompressWhitespace();
|
||||
if (!aName.IsEmpty())
|
||||
return;
|
||||
return eNameOK;
|
||||
|
||||
// Can get text from title of <toolbaritem> if we're a child of a <toolbaritem>
|
||||
nsIContent *bindingParent = mContent->GetBindingParent();
|
||||
|
@ -1138,12 +1138,13 @@ Accessible::GetXULName(nsString& aName)
|
|||
if (parent->Tag() == nsGkAtoms::toolbaritem &&
|
||||
parent->GetAttr(kNameSpaceID_None, nsGkAtoms::title, aName)) {
|
||||
aName.CompressWhitespace();
|
||||
return;
|
||||
return eNameOK;
|
||||
}
|
||||
parent = parent->GetParent();
|
||||
}
|
||||
|
||||
nsTextEquivUtils::GetNameFromSubtree(this, aName);
|
||||
return aName.IsEmpty() ? eNameOK : eNameFromSubtree;
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -1229,6 +1230,13 @@ Accessible::GetAttributes(nsIPersistentProperties **aAttributes)
|
|||
if (State() & states::CHECKABLE)
|
||||
nsAccUtils::SetAccAttr(attributes, nsGkAtoms::checkable, NS_LITERAL_STRING("true"));
|
||||
|
||||
// Expose 'explicit-name' attribute.
|
||||
if (!nsTextEquivUtils::IsNameFromSubtreeAllowed(this) ||
|
||||
Name(oldValueUnused) != eNameFromSubtree) {
|
||||
attributes->SetStringProperty(NS_LITERAL_CSTRING("explicit-name"),
|
||||
NS_LITERAL_STRING("true"), oldValueUnused);
|
||||
}
|
||||
|
||||
// Group attributes (level/setsize/posinset)
|
||||
GroupPos groupPos = GroupPosition();
|
||||
nsAccUtils::SetAccGroupAttrs(attributes, groupPos.level,
|
||||
|
@ -2420,23 +2428,18 @@ Accessible::Shutdown()
|
|||
|
||||
// Accessible protected
|
||||
void
|
||||
Accessible::ARIAName(nsAString& aName)
|
||||
Accessible::ARIAName(nsString& aName)
|
||||
{
|
||||
nsAutoString label;
|
||||
|
||||
// aria-labelledby now takes precedence over aria-label
|
||||
nsresult rv = nsTextEquivUtils::
|
||||
GetTextEquivFromIDRefs(this, nsGkAtoms::aria_labelledby, label);
|
||||
GetTextEquivFromIDRefs(this, nsGkAtoms::aria_labelledby, aName);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
label.CompressWhitespace();
|
||||
aName = label;
|
||||
aName.CompressWhitespace();
|
||||
}
|
||||
|
||||
if (label.IsEmpty() &&
|
||||
mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::aria_label,
|
||||
label)) {
|
||||
label.CompressWhitespace();
|
||||
aName = label;
|
||||
if (aName.IsEmpty() &&
|
||||
mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::aria_label, aName)) {
|
||||
aName.CompressWhitespace();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2445,9 +2448,10 @@ ENameValueFlag
|
|||
Accessible::NativeName(nsString& aName)
|
||||
{
|
||||
if (mContent->IsHTML())
|
||||
GetHTMLName(aName);
|
||||
else if (mContent->IsXUL())
|
||||
GetXULName(aName);
|
||||
return GetHTMLName(aName);
|
||||
|
||||
if (mContent->IsXUL())
|
||||
return GetXULName(aName);
|
||||
|
||||
return eNameOK;
|
||||
}
|
||||
|
|
|
@ -58,6 +58,11 @@ enum ENameValueFlag {
|
|||
*/
|
||||
eNoNameOnPurpose,
|
||||
|
||||
/**
|
||||
* Name was computed from the subtree.
|
||||
*/
|
||||
eNameFromSubtree,
|
||||
|
||||
/**
|
||||
* Tooltip was used as a name.
|
||||
*/
|
||||
|
@ -805,13 +810,13 @@ protected:
|
|||
/**
|
||||
* Returns the accessible name specified by ARIA.
|
||||
*/
|
||||
void ARIAName(nsAString& aName);
|
||||
void ARIAName(nsString& aName);
|
||||
|
||||
/**
|
||||
* Compute the name of HTML/XUL node.
|
||||
*/
|
||||
void GetHTMLName(nsString& aName);
|
||||
void GetXULName(nsString& aName);
|
||||
mozilla::a11y::ENameValueFlag GetHTMLName(nsString& aName);
|
||||
mozilla::a11y::ENameValueFlag GetXULName(nsString& aName);
|
||||
|
||||
// helper method to verify frames
|
||||
static nsresult GetFullKeyName(const nsAString& aModifierName, const nsAString& aKeyName, nsAString& aStringOut);
|
||||
|
|
|
@ -1953,12 +1953,14 @@ HyperTextAccessible::ScrollSubstringToPoint(int32_t aStartIndex,
|
|||
ENameValueFlag
|
||||
HyperTextAccessible::NativeName(nsString& aName)
|
||||
{
|
||||
AccessibleWrap::NativeName(aName);
|
||||
ENameValueFlag nameFlag = AccessibleWrap::NativeName(aName);
|
||||
if (!aName.IsEmpty())
|
||||
return nameFlag;
|
||||
|
||||
// Get name from title attribute for HTML abbr and acronym elements making it
|
||||
// a valid name from markup. Otherwise their name isn't picked up by recursive
|
||||
// name computation algorithm. See NS_OK_NAME_FROM_TOOLTIP.
|
||||
if (aName.IsEmpty() && IsAbbreviation() &&
|
||||
if (IsAbbreviation() &&
|
||||
mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::title, aName))
|
||||
aName.CompressWhitespace();
|
||||
|
||||
|
|
|
@ -77,16 +77,15 @@ ImageAccessible::NativeName(nsString& aName)
|
|||
if (!aName.IsEmpty())
|
||||
return eNameOK;
|
||||
|
||||
Accessible::NativeName(aName);
|
||||
if (aName.IsEmpty() && hasAltAttrib) {
|
||||
// No accessible name but empty 'alt' attribute is present. If further name
|
||||
// computation algorithm doesn't provide non empty name then it means
|
||||
// an empty 'alt' attribute was used to indicate a decorative image (see
|
||||
// nsIAccessible::name attribute for details).
|
||||
return eNoNameOnPurpose;
|
||||
}
|
||||
ENameValueFlag nameFlag = Accessible::NativeName(aName);
|
||||
if (!aName.IsEmpty())
|
||||
return nameFlag;
|
||||
|
||||
return eNameOK;
|
||||
// No accessible name but empty 'alt' attribute is present. If further name
|
||||
// computation algorithm doesn't provide non empty name then it means
|
||||
// an empty 'alt' attribute was used to indicate a decorative image (see
|
||||
// Accessible::Name() method for details).
|
||||
return hasAltAttrib ? eNoNameOnPurpose : eNameOK;
|
||||
}
|
||||
|
||||
role
|
||||
|
|
|
@ -58,7 +58,7 @@ ENameValueFlag
|
|||
HTMLLabelAccessible::NativeName(nsString& aName)
|
||||
{
|
||||
nsTextEquivUtils::GetNameFromSubtree(this, aName);
|
||||
return eNameOK;
|
||||
return aName.IsEmpty() ? eNameOK : eNameFromSubtree;
|
||||
}
|
||||
|
||||
role
|
||||
|
|
|
@ -259,13 +259,13 @@ HTMLButtonAccessible::NativeRole()
|
|||
ENameValueFlag
|
||||
HTMLButtonAccessible::NativeName(nsString& aName)
|
||||
{
|
||||
Accessible::NativeName(aName);
|
||||
ENameValueFlag nameFlag = Accessible::NativeName(aName);
|
||||
if (!aName.IsEmpty() || mContent->Tag() != nsGkAtoms::input)
|
||||
return eNameOK;
|
||||
return nameFlag;
|
||||
|
||||
// No name from HTML or ARIA
|
||||
if (!mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::value, aName) &&
|
||||
!mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::alt, aName)) {
|
||||
// Note: No need to check @value attribute since it results in anonymous text
|
||||
// node. The name is calculated from subtree in this case.
|
||||
if (!mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::alt, aName)) {
|
||||
// Use the button's (default) label if nothing else works
|
||||
nsIFrame* frame = GetFrame();
|
||||
if (frame) {
|
||||
|
@ -323,9 +323,9 @@ HTMLTextFieldAccessible::NativeRole()
|
|||
ENameValueFlag
|
||||
HTMLTextFieldAccessible::NativeName(nsString& aName)
|
||||
{
|
||||
Accessible::NativeName(aName);
|
||||
ENameValueFlag nameFlag = Accessible::NativeName(aName);
|
||||
if (!aName.IsEmpty())
|
||||
return eNameOK;
|
||||
return nameFlag;
|
||||
|
||||
if (mContent->GetBindingParent()) {
|
||||
// XXX: bug 459640
|
||||
|
@ -613,9 +613,9 @@ HTMLGroupboxAccessible::GetLegend()
|
|||
ENameValueFlag
|
||||
HTMLGroupboxAccessible::NativeName(nsString& aName)
|
||||
{
|
||||
Accessible::NativeName(aName);
|
||||
ENameValueFlag nameFlag = Accessible::NativeName(aName);
|
||||
if (!aName.IsEmpty())
|
||||
return eNameOK;
|
||||
return nameFlag;
|
||||
|
||||
nsIContent* legendContent = GetLegend();
|
||||
if (legendContent)
|
||||
|
@ -696,9 +696,9 @@ HTMLFigureAccessible::NativeRole()
|
|||
ENameValueFlag
|
||||
HTMLFigureAccessible::NativeName(nsString& aName)
|
||||
{
|
||||
HyperTextAccessibleWrap::NativeName(aName);
|
||||
ENameValueFlag nameFlag = HyperTextAccessibleWrap::NativeName(aName);
|
||||
if (!aName.IsEmpty())
|
||||
return eNameOK;
|
||||
return nameFlag;
|
||||
|
||||
nsIContent* captionContent = Caption();
|
||||
if (captionContent)
|
||||
|
|
|
@ -163,9 +163,9 @@ HTMLAreaAccessible::
|
|||
ENameValueFlag
|
||||
HTMLAreaAccessible::NativeName(nsString& aName)
|
||||
{
|
||||
Accessible::NativeName(aName);
|
||||
ENameValueFlag nameFlag = Accessible::NativeName(aName);
|
||||
if (!aName.IsEmpty())
|
||||
return eNameOK;
|
||||
return nameFlag;
|
||||
|
||||
if (!mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::alt, aName))
|
||||
GetValue(aName);
|
||||
|
|
|
@ -200,6 +200,7 @@ HTMLSelectOptionAccessible::NativeName(nsString& aName)
|
|||
if (text && text->IsNodeOfType(nsINode::eTEXT)) {
|
||||
nsTextEquivUtils::AppendTextEquivFromTextContent(text, &aName);
|
||||
aName.CompressWhitespace();
|
||||
return aName.IsEmpty() ? eNameOK : eNameFromSubtree;
|
||||
}
|
||||
|
||||
return eNameOK;
|
||||
|
|
|
@ -388,9 +388,9 @@ HTMLTableAccessible::NativeState()
|
|||
ENameValueFlag
|
||||
HTMLTableAccessible::NativeName(nsString& aName)
|
||||
{
|
||||
Accessible::NativeName(aName);
|
||||
ENameValueFlag nameFlag = Accessible::NativeName(aName);
|
||||
if (!aName.IsEmpty())
|
||||
return eNameOK;
|
||||
return nameFlag;
|
||||
|
||||
// Use table caption as a name.
|
||||
Accessible* caption = Caption();
|
||||
|
|
|
@ -125,10 +125,11 @@ ENameValueFlag
|
|||
XULLinkAccessible::NativeName(nsString& aName)
|
||||
{
|
||||
mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::value, aName);
|
||||
if (aName.IsEmpty())
|
||||
nsTextEquivUtils::GetNameFromSubtree(this, aName);
|
||||
if (!aName.IsEmpty())
|
||||
return eNameOK;
|
||||
|
||||
return eNameOK;
|
||||
nsTextEquivUtils::GetNameFromSubtree(this, aName);
|
||||
return aName.IsEmpty() ? eNameOK : eNameFromSubtree;
|
||||
}
|
||||
|
||||
role
|
||||
|
|
|
@ -634,8 +634,7 @@ XULListitemAccessible::NativeName(nsString& aName)
|
|||
}
|
||||
}
|
||||
|
||||
GetXULName(aName);
|
||||
return eNameOK;
|
||||
return GetXULName(aName);
|
||||
}
|
||||
|
||||
role
|
||||
|
|
|
@ -188,6 +188,11 @@ function testNameForAttrRule(aElm, aRule)
|
|||
|
||||
var msg = "Attribute '" + attr + "' test. ";
|
||||
testName(aElm, name, msg);
|
||||
if (aRule.getAttribute("explict-name") != "false")
|
||||
testAttrs(aElm, {"explicit-name" : "true"}, true);
|
||||
else
|
||||
testAbsentAttrs(aElm, {"explicit-name" : "true"});
|
||||
|
||||
aElm.removeAttribute(attr);
|
||||
|
||||
gTestIterator.iterateNext();
|
||||
|
@ -235,6 +240,7 @@ function testNameForElmRule(aElm, aRule)
|
|||
|
||||
var msg = "Element '" + tagname + "' test.";
|
||||
testName(aElm, labelElm.getAttribute("a11yname"), msg);
|
||||
testAttrs(aElm, {"explicit-name" : "true"}, true);
|
||||
|
||||
var parentNode = labelElm.parentNode;
|
||||
|
||||
|
@ -252,6 +258,7 @@ function testNameForSubtreeRule(aElm, aRule)
|
|||
{
|
||||
var msg = "From subtree test.";
|
||||
testName(aElm, aElm.getAttribute("a11yname"), msg);
|
||||
testAbsentAttrs(aElm, {"explicit-name" : "true"});
|
||||
|
||||
if (gDumpToConsole) {
|
||||
dump("\nProcessed from subtree rule. Wait for reorder event on " +
|
||||
|
|
|
@ -125,7 +125,7 @@
|
|||
<!-- specific -->
|
||||
<ruleset id="htmlinputbutton">
|
||||
<ruleset ref="htmlelm_start"/>
|
||||
<rule attr="value" type="string"/>
|
||||
<rule attr="value" type="string" explict-name="false"/>
|
||||
<rule attr="alt" type="string"/>
|
||||
<rule attr="src" type="string"/>
|
||||
<rule attr="data" type="string"/>
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
src="../events.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../name.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../attributes.js"></script>
|
||||
|
||||
<script type="application/javascript"
|
||||
src="markup.js"></script>
|
||||
|
|
Загрузка…
Ссылка в новой задаче