Bug 395699 - relations not working when pointing to a <span> r=surkov.alexander a=mtschrep

This commit is contained in:
Evan.Yan@Sun.COM 2008-01-21 19:17:37 -08:00
parent 27f1e406c3
commit 16b37806bc
3 changed files with 106 additions and 23 deletions

View File

@ -1196,6 +1196,34 @@ nsresult nsAccessibilityService::InitAccessible(nsIAccessible *aAccessibleIn,
return rv;
}
static PRBool HasRelatedContent(nsIContent *aContent)
{
nsAutoString id;
if (!aContent || !nsAccUtils::GetID(aContent, id) || id.IsEmpty()) {
return PR_FALSE;
}
nsIAtom *relationAttrs[] = {nsAccessibilityAtoms::aria_labelledby,
nsAccessibilityAtoms::aria_describedby,
nsAccessibilityAtoms::aria_owns,
nsAccessibilityAtoms::aria_controls,
nsAccessibilityAtoms::aria_flowto};
if (nsAccUtils::FindNeighbourPointingToNode(aContent, relationAttrs, NS_ARRAY_LENGTH(relationAttrs))) {
return PR_TRUE;
}
nsIContent *ancestorContent = aContent;
nsAutoString activeID;
while ((ancestorContent = ancestorContent->GetParent()) != nsnull) {
if (ancestorContent->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_activedescendant, activeID)) {
// ancestor has activedescendant property, this content could be active
return PR_TRUE;
}
}
return PR_FALSE;
}
NS_IMETHODIMP nsAccessibilityService::GetAccessible(nsIDOMNode *aNode,
nsIPresShell *aPresShell,
nsIWeakReference *aWeakShell,
@ -1468,7 +1496,8 @@ NS_IMETHODIMP nsAccessibilityService::GetAccessible(nsIDOMNode *aNode,
if (!newAcc && content->Tag() != nsAccessibilityAtoms::body && content->GetParent() &&
(content->IsFocusable() ||
(isHTML && nsAccUtils::HasListener(content, NS_LITERAL_STRING("click"))) ||
HasUniversalAriaProperty(content, aWeakShell) || roleMapEntry)) {
HasUniversalAriaProperty(content, aWeakShell) || roleMapEntry) ||
HasRelatedContent(content)) {
// This content is focusable or has an interesting dynamic content accessibility property.
// If it's interesting we need it in the accessibility hierarchy so that events or
// other accessibles can point to it, or so that it can hold a state, etc.

View File

@ -586,6 +586,16 @@ nsAccUtils::FindNeighbourPointingToNode(nsIContent *aForNode,
nsIAtom *aRelationAttr,
nsIAtom *aTagName,
PRUint32 aAncestorLevelsToSearch)
{
return FindNeighbourPointingToNode(aForNode, &aRelationAttr, 1, aTagName, aAncestorLevelsToSearch);
}
nsIContent*
nsAccUtils::FindNeighbourPointingToNode(nsIContent *aForNode,
nsIAtom **aRelationAttrs,
PRUint32 aAttrNum,
nsIAtom *aTagName,
PRUint32 aAncestorLevelsToSearch)
{
nsCOMPtr<nsIContent> binding;
nsAutoString controlID;
@ -638,14 +648,16 @@ nsAccUtils::FindNeighbourPointingToNode(nsIContent *aForNode,
if (content != prevSearched) {
labelContent = FindDescendantPointingToID(&controlID, content,
aRelationAttr, nsnull, aTagName);
aRelationAttrs, aAttrNum,
nsnull, aTagName);
}
}
break;
}
labelContent = FindDescendantPointingToID(&controlID, aForNode,
aRelationAttr, prevSearched, aTagName);
aRelationAttrs, aAttrNum,
prevSearched, aTagName);
prevSearched = aForNode;
}
@ -656,7 +668,8 @@ nsAccUtils::FindNeighbourPointingToNode(nsIContent *aForNode,
nsIContent*
nsAccUtils::FindDescendantPointingToID(const nsString *aId,
nsIContent *aLookContent,
nsIAtom *aRelationAttr,
nsIAtom **aRelationAttrs,
PRUint32 aAttrNum,
nsIContent *aExcludeContent,
nsIAtom *aTagType)
{
@ -665,31 +678,45 @@ nsAccUtils::FindDescendantPointingToID(const nsString *aId,
LossyAppendUTF16toASCII(*aId, idWithSpaces);
idWithSpaces += ' ';
return FindDescendantPointingToIDImpl(idWithSpaces, aLookContent,
aRelationAttr, aExcludeContent, aTagType);
aRelationAttrs, aAttrNum,
aExcludeContent, aTagType);
}
nsIContent*
nsAccUtils::FindDescendantPointingToID(const nsString *aId,
nsIContent *aLookContent,
nsIAtom *aRelationAttr,
nsIContent *aExcludeContent,
nsIAtom *aTagType)
{
return FindDescendantPointingToID(aId, aLookContent, &aRelationAttr, 1, aExcludeContent, aTagType);
}
nsIContent*
nsAccUtils::FindDescendantPointingToIDImpl(nsCString& aIdWithSpaces,
nsIContent *aLookContent,
nsIAtom *aRelationAttr,
nsIAtom **aRelationAttrs,
PRUint32 aAttrNum,
nsIContent *aExcludeContent,
nsIAtom *aTagType)
{
NS_ENSURE_TRUE(aLookContent, nsnull);
NS_ENSURE_TRUE(aRelationAttr, nsnull);
NS_ENSURE_TRUE(aRelationAttrs && *aRelationAttrs, nsnull);
if (!aTagType || aLookContent->Tag() == aTagType) {
// Tag matches
// Check for ID in the attribute aRelationAttr, which can be a list
nsAutoString idList;
if (aLookContent->GetAttr(kNameSpaceID_None, aRelationAttr, idList)) {
idList.Insert(' ', 0); // Surround idlist with spaces for search
idList.Append(' ');
// idList is now a set of id's with spaces around each,
// and id also has spaces around it.
// If id is a substring of idList then we have a match
if (idList.Find(aIdWithSpaces) != -1) {
return aLookContent;
// Check for ID in the attributes aRelationAttrs, which can be a list
for (PRUint32 i = 0; i < aAttrNum; i++) {
nsAutoString idList;
if (aLookContent->GetAttr(kNameSpaceID_None, aRelationAttrs[i], idList)) {
idList.Insert(' ', 0); // Surround idlist with spaces for search
idList.Append(' ');
// idList is now a set of id's with spaces around each,
// and id also has spaces around it.
// If id is a substring of idList then we have a match
if (idList.Find(aIdWithSpaces) != -1) {
return aLookContent;
}
}
}
if (aTagType) {
@ -707,7 +734,8 @@ nsAccUtils::FindDescendantPointingToIDImpl(nsCString& aIdWithSpaces,
while ((child = aLookContent->GetChildAt(count++)) != nsnull) {
if (child != aExcludeContent) {
labelContent = FindDescendantPointingToIDImpl(aIdWithSpaces, child,
aRelationAttr, aExcludeContent, aTagType);
aRelationAttrs, aAttrNum,
aExcludeContent, aTagType);
if (labelContent) {
return labelContent;
}

View File

@ -277,15 +277,27 @@ public:
* attribute value that equals to ID attribute of the given element.
* ID attribute can be either 'id' attribute or 'anonid' if the element is
* anonymous.
* The first matched content will be returned.
*
* @param aForNode - the given element the search is performed for
* @param aRelationAttr - attribute name of searched element, ignored if aAriaProperty passed in
* @param aRelationAttrs - an array of attributes, element is attribute name of searched element, ignored if aAriaProperty passed in
* @param aAttrNum - how many attributes in aRelationAttrs
* @param aTagName - tag name of searched element, or nsnull for any -- ignored if aAriaProperty passed in
* @param aAncestorLevelsToSearch - points how is the neighborhood of the
* given element big.
*/
static nsIContent *FindNeighbourPointingToNode(nsIContent *aForNode,
nsIAtom *aRelationAttr,
nsIAtom **aRelationAttrs,
PRUint32 aAttrNum,
nsIAtom *aTagName = nsnull,
PRUint32 aAncestorLevelsToSearch = 5);
/**
* Overloaded version of FindNeighbourPointingToNode to accept only one
* relation attribute.
*/
static nsIContent *FindNeighbourPointingToNode(nsIContent *aForNode,
nsIAtom *aRelationAttr,
nsIAtom *aTagName = nsnull,
PRUint32 aAncestorLevelsToSearch = 5);
@ -293,15 +305,28 @@ public:
* Search for element that satisfies the requirements in subtree of the given
* element. The requirements are tag name, attribute name and value of
* attribute.
* The first matched content will be returned.
*
* @param aId - value of searched attribute
* @param aLookContent - element that search is performed inside
* @param aRelationAttr - searched attribute
* @param if both aAriaProperty and aRelationAttr are null, then any element with aTagType will do
* @param aRelationAttrs - an array of searched attributes
* @param aAttrNum - how many attributes in aRelationAttrs
* @param if both aAriaProperty and aRelationAttrs are null, then any element with aTagType will do
* @param aExcludeContent - element that is skiped for search
* @param aTagType - tag name of searched element, by default it is 'label' --
* ignored if aAriaProperty passed in
*/
static nsIContent *FindDescendantPointingToID(const nsString *aId,
nsIContent *aLookContent,
nsIAtom **aRelationAttrs,
PRUint32 aAttrNum = 1,
nsIContent *aExcludeContent = nsnull,
nsIAtom *aTagType = nsAccessibilityAtoms::label);
/**
* Overloaded version of FindDescendantPointingToID to accept only one
* relation attribute.
*/
static nsIContent *FindDescendantPointingToID(const nsString *aId,
nsIContent *aLookContent,
nsIAtom *aRelationAttr,
@ -311,7 +336,8 @@ public:
// Helper for FindDescendantPointingToID(), same args
static nsIContent *FindDescendantPointingToIDImpl(nsCString& aIdWithSpaces,
nsIContent *aLookContent,
nsIAtom *aRelationAttrs,
nsIAtom **aRelationAttrs,
PRUint32 aAttrNum = 1,
nsIContent *aExcludeContent = nsnull,
nsIAtom *aTagType = nsAccessibilityAtoms::label);
};