зеркало из https://github.com/mozilla/pjs.git
Bug 480099 - If an html:label has both a title and inner text, title becomes acc name for control this label is labelling, r=marcoz, davidb
This commit is contained in:
Родитель
8f64d4b704
Коммит
ae4701c348
|
@ -308,10 +308,12 @@ nsAccessible::GetName(nsAString& aName)
|
|||
if (content->GetAttr(kNameSpaceID_None, tooltipAttr, name)) {
|
||||
name.CompressWhitespace();
|
||||
aName = name;
|
||||
} else if (rv != NS_OK_EMPTY_NAME) {
|
||||
aName.SetIsVoid(PR_TRUE);
|
||||
return NS_OK_NAME_FROM_TOOLTIP;
|
||||
}
|
||||
|
||||
if (rv != NS_OK_EMPTY_NAME)
|
||||
aName.SetIsVoid(PR_TRUE);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -77,6 +77,10 @@ NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_GENERAL, 0x21)
|
|||
#define NS_OK_EMPTY_NAME \
|
||||
NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_GENERAL, 0x23)
|
||||
|
||||
// see nsAccessible::GetNameInternal
|
||||
#define NS_OK_NAME_FROM_TOOLTIP \
|
||||
NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_GENERAL, 0x25)
|
||||
|
||||
// Saves a data member -- if child count equals this value we haven't
|
||||
// cached children or child count yet
|
||||
enum { eChildCountUninitialized = -1 };
|
||||
|
|
|
@ -239,15 +239,16 @@ nsTextEquivUtils::AppendFromAccessibleChildren(nsIAccessible *aAccessible,
|
|||
nsCOMPtr<nsIAccessible> accChild, accNextChild;
|
||||
aAccessible->GetFirstChild(getter_AddRefs(accChild));
|
||||
|
||||
nsresult rv = NS_OK_NO_NAME_CLAUSE_HANDLED;
|
||||
while (accChild) {
|
||||
nsresult rv = AppendFromAccessible(accChild, aString);
|
||||
rv = AppendFromAccessible(accChild, aString);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
accChild->GetNextSibling(getter_AddRefs(accNextChild));
|
||||
accChild.swap(accNextChild);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -271,49 +272,88 @@ nsTextEquivUtils::AppendFromAccessible(nsIAccessible *aAccessible,
|
|||
nsresult rv = aAccessible->GetName(text);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
AppendString(aString, text);
|
||||
PRBool isEmptyTextEquiv = PR_TRUE;
|
||||
|
||||
PRUint32 role = nsAccUtils::Role(aAccessible);
|
||||
PRUint32 nameRule = gRoleToNameRulesMap[role];
|
||||
// If the name is from tooltip then append it to result string in the end
|
||||
// (see h. step of name computation guide).
|
||||
if (rv != NS_OK_NAME_FROM_TOOLTIP)
|
||||
isEmptyTextEquiv = !AppendString(aString, text);
|
||||
|
||||
if (nameRule == eFromValue) {
|
||||
// Implementation of step f) of text equivalent computation. If the given
|
||||
// accessible is not root accessible (the accessible the text equivalent is
|
||||
// computed for in the end) then append accessible value. Otherwise append
|
||||
// value if and only if the given accessible is in the middle of its parent.
|
||||
// Implementation of f. step.
|
||||
rv = AppendFromValue(aAccessible, aString);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (aAccessible != gInitiatorAcc) {
|
||||
rv = aAccessible->GetValue(text);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
AppendString(aString, text);
|
||||
} else {
|
||||
nsCOMPtr<nsIAccessible> nextSibling;
|
||||
aAccessible->GetNextSibling(getter_AddRefs(nextSibling));
|
||||
if (nextSibling) {
|
||||
nsCOMPtr<nsIAccessible> parent;
|
||||
aAccessible->GetParent(getter_AddRefs(parent));
|
||||
if (parent) {
|
||||
nsCOMPtr<nsIAccessible> firstChild;
|
||||
parent->GetFirstChild(getter_AddRefs(firstChild));
|
||||
if (firstChild && firstChild != aAccessible) {
|
||||
rv = aAccessible->GetValue(text);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
AppendString(aString, text);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (rv != NS_OK_NO_NAME_CLAUSE_HANDLED)
|
||||
isEmptyTextEquiv = PR_FALSE;
|
||||
|
||||
// Implementation of g) step of text equivalent computation guide. Go down
|
||||
// into subtree if accessible allows "text equivalent from subtree rule" or
|
||||
// it's not root and not control.
|
||||
if (text.IsEmpty() && (nameRule & eFromSubtreeIfRec))
|
||||
return AppendFromAccessibleChildren(aAccessible, aString);
|
||||
if (isEmptyTextEquiv) {
|
||||
PRUint32 role = nsAccUtils::Role(aAccessible);
|
||||
PRUint32 nameRule = gRoleToNameRulesMap[role];
|
||||
|
||||
return NS_OK;
|
||||
if (nameRule & eFromSubtreeIfRec) {
|
||||
rv = AppendFromAccessibleChildren(aAccessible, aString);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (rv != NS_OK_NO_NAME_CLAUSE_HANDLED)
|
||||
isEmptyTextEquiv = PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// Implementation of h. step
|
||||
if (isEmptyTextEquiv && !text.IsEmpty()) {
|
||||
AppendString(aString, text);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsTextEquivUtils::AppendFromValue(nsIAccessible *aAccessible,
|
||||
nsAString *aString)
|
||||
{
|
||||
PRUint32 role = nsAccUtils::Role(aAccessible);
|
||||
PRUint32 nameRule = gRoleToNameRulesMap[role];
|
||||
|
||||
if (nameRule != eFromValue)
|
||||
return NS_OK_NO_NAME_CLAUSE_HANDLED;
|
||||
|
||||
// Implementation of step f. of text equivalent computation. If the given
|
||||
// accessible is not root accessible (the accessible the text equivalent is
|
||||
// computed for in the end) then append accessible value. Otherwise append
|
||||
// value if and only if the given accessible is in the middle of its parent.
|
||||
|
||||
nsAutoString text;
|
||||
if (aAccessible != gInitiatorAcc) {
|
||||
nsresult rv = aAccessible->GetValue(text);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return AppendString(aString, text) ?
|
||||
NS_OK : NS_OK_NO_NAME_CLAUSE_HANDLED;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIAccessible> nextSibling;
|
||||
aAccessible->GetNextSibling(getter_AddRefs(nextSibling));
|
||||
if (nextSibling) {
|
||||
nsCOMPtr<nsIAccessible> parent;
|
||||
aAccessible->GetParent(getter_AddRefs(parent));
|
||||
if (parent) {
|
||||
nsCOMPtr<nsIAccessible> firstChild;
|
||||
parent->GetFirstChild(getter_AddRefs(firstChild));
|
||||
if (firstChild && firstChild != aAccessible) {
|
||||
nsresult rv = aAccessible->GetValue(text);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return AppendString(aString, text) ?
|
||||
NS_OK : NS_OK_NO_NAME_CLAUSE_HANDLED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK_NO_NAME_CLAUSE_HANDLED;
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -364,18 +404,19 @@ nsTextEquivUtils::AppendFromDOMNode(nsIContent *aContent, nsAString *aString)
|
|||
return AppendFromDOMChildren(aContent, aString);
|
||||
}
|
||||
|
||||
void
|
||||
PRBool
|
||||
nsTextEquivUtils::AppendString(nsAString *aString,
|
||||
const nsAString& aTextEquivalent)
|
||||
{
|
||||
// Insert spaces to insure that words from controls aren't jammed together.
|
||||
if (aTextEquivalent.IsEmpty())
|
||||
return;
|
||||
return PR_FALSE;
|
||||
|
||||
if (!aString->IsEmpty())
|
||||
aString->Append(PRUnichar(' '));
|
||||
|
||||
aString->Append(aTextEquivalent);
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -135,6 +135,11 @@ private:
|
|||
static nsresult AppendFromAccessible(nsIAccessible *aAccessible,
|
||||
nsAString *aString);
|
||||
|
||||
/**
|
||||
* Calculates text equivalent from the value of given accessible.
|
||||
*/
|
||||
static nsresult AppendFromValue(nsIAccessible *aAccessible,
|
||||
nsAString *aString);
|
||||
/**
|
||||
* Iterates DOM children and calculates text equivalent from each child node.
|
||||
*/
|
||||
|
@ -148,9 +153,11 @@ private:
|
|||
static nsresult AppendFromDOMNode(nsIContent *aContent, nsAString *aString);
|
||||
|
||||
/**
|
||||
* Concatenates strings and appends space between them.
|
||||
* Concatenates strings and appends space between them. Returns true if
|
||||
* text equivalent string was appended.
|
||||
*/
|
||||
static void AppendString(nsAString *aString, const nsAString& aTextEquivalent);
|
||||
static PRBool AppendString(nsAString *aString,
|
||||
const nsAString& aTextEquivalent);
|
||||
|
||||
/**
|
||||
* Map array from roles to name rules (constants of ETextEquivRule).
|
||||
|
|
|
@ -79,6 +79,16 @@
|
|||
// Gets the name from text nodes. Element br adds space between them.
|
||||
testName("btn_labelledby_mixed_br", "text text");
|
||||
|
||||
// Gets the name from label content which allows name from subtree,
|
||||
// ignore @title attribute on label
|
||||
testName("from_label_ignoretitle", "Country:");
|
||||
|
||||
// Gets the name from html:p content, which doesn't allow name from
|
||||
// subtree, ignore @title attribute on label
|
||||
testName("from_p_ignoretitle", "Choose country from.");
|
||||
|
||||
// Gets the name from html:input value, ignore @title attribute on input
|
||||
testName("from_input_ignoretitle", "Custom country");
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// label element
|
||||
|
@ -266,6 +276,31 @@
|
|||
aria-labelledby="labelledby_mixed_br">9</button>
|
||||
<br/>
|
||||
|
||||
<!-- the name from subtree, name from label content rather than from its title
|
||||
attribute -->
|
||||
<label for="from_label_ignoretitle"
|
||||
title="Select your country of origin">Country:</label>
|
||||
<select id="from_label_ignoretitle">
|
||||
<option>Germany</option>
|
||||
<option>Russia</option>
|
||||
</select>
|
||||
|
||||
<!-- the name from subtree, name from html:p content rather than from its
|
||||
title attribute -->
|
||||
<p id="p_ignoretitle"
|
||||
title="Select your country of origin">Choose country from.</p>
|
||||
<select id="from_p_ignoretitle" aria-labelledby="p_ignoretitle">
|
||||
<option>Germany</option>
|
||||
<option>Russia</option>
|
||||
</select>
|
||||
|
||||
<!-- the name from subtree, name from html:input value rather than from its
|
||||
title attribute -->
|
||||
<p id="from_input_ignoretitle" aria-labelledby="input_ignoretitle">Country</p>
|
||||
<input id="input_ignoretitle"
|
||||
value="Custom country"
|
||||
title="Input your country of origin"/ >
|
||||
|
||||
<!-- label element, label contains the button -->
|
||||
<label>text<button id="btn_label_inside">10</button>text</label>
|
||||
<br/>
|
||||
|
|
Загрузка…
Ссылка в новой задаче