diff --git a/accessible/src/base/nsAccessibilityAtomList.h b/accessible/src/base/nsAccessibilityAtomList.h index 04cf884d7a78..fd6197bb1941 100755 --- a/accessible/src/base/nsAccessibilityAtomList.h +++ b/accessible/src/base/nsAccessibilityAtomList.h @@ -165,7 +165,7 @@ ACCESSIBILITY_ATOM(droppable, "droppable") // XUL combo box ACCESSIBILITY_ATOM(editable, "editable") ACCESSIBILITY_ATOM(_for, "for") ACCESSIBILITY_ATOM(hidden, "hidden") // XUL tree columns -ACCESSIBILITY_ATOM(href, "href") +ACCESSIBILITY_ATOM(href, "href") // XUL, XLink ACCESSIBILITY_ATOM(increment, "increment") // XUL ACCESSIBILITY_ATOM(lang, "lang") ACCESSIBILITY_ATOM(linkedPanel, "linkedpanel") // XUL @@ -175,6 +175,7 @@ ACCESSIBILITY_ATOM(multiline, "multiline") // XUL ACCESSIBILITY_ATOM(name, "name") ACCESSIBILITY_ATOM(onclick, "onclick") ACCESSIBILITY_ATOM(readonly, "readonly") +ACCESSIBILITY_ATOM(simple, "simple") // XLink ACCESSIBILITY_ATOM(src, "src") ACCESSIBILITY_ATOM(selected, "selected") ACCESSIBILITY_ATOM(summary, "summary") diff --git a/accessible/src/base/nsAccessibilityService.cpp b/accessible/src/base/nsAccessibilityService.cpp index 06fb603d5ba7..2faefe5fa037 100644 --- a/accessible/src/base/nsAccessibilityService.cpp +++ b/accessible/src/base/nsAccessibilityService.cpp @@ -1579,7 +1579,7 @@ NS_IMETHODIMP nsAccessibilityService::GetAccessible(nsIDOMNode *aNode, (content->IsFocusable() || (isHTML && nsAccUtils::HasListener(content, NS_LITERAL_STRING("click"))) || HasUniversalAriaProperty(content, aWeakShell) || roleMapEntry || - HasRelatedContent(content))) { + HasRelatedContent(content) || nsAccUtils::IsXLink(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. diff --git a/accessible/src/base/nsAccessibilityUtils.cpp b/accessible/src/base/nsAccessibilityUtils.cpp index 445730fd08fb..5db2dab0d6d0 100755 --- a/accessible/src/base/nsAccessibilityUtils.cpp +++ b/accessible/src/base/nsAccessibilityUtils.cpp @@ -722,6 +722,14 @@ nsAccUtils::GetID(nsIContent *aContent, nsAString& aID) return idAttribute ? aContent->GetAttr(kNameSpaceID_None, idAttribute, aID) : PR_FALSE; } +PRBool +nsAccUtils::IsXLink(nsIContent *aContent) +{ + return aContent->AttrValueIs(kNameSpaceID_XLink, nsAccessibilityAtoms::type, + nsAccessibilityAtoms::simple, eCaseMatters) && + aContent->HasAttr(kNameSpaceID_XLink, nsAccessibilityAtoms::href); +} + nsIContent* nsAccUtils::FindNeighbourPointingToNode(nsIContent *aForNode, nsIAtom *aRelationAttr, diff --git a/accessible/src/base/nsAccessibilityUtils.h b/accessible/src/base/nsAccessibilityUtils.h index 9672fbf42a24..2f7d8a491216 100755 --- a/accessible/src/base/nsAccessibilityUtils.h +++ b/accessible/src/base/nsAccessibilityUtils.h @@ -294,6 +294,14 @@ public: */ static PRBool GetID(nsIContent *aContent, nsAString& aID); + /** + * Check if the given element is XLink. + * + * @param aContent the given element + * @return PR_TRUE if the given element is XLink + */ + static PRBool IsXLink(nsIContent *aContent); + /** * Get the role map entry for a given DOM node. This will use the first * ARIA role if the role attribute provides a space delimited list of roles. diff --git a/accessible/src/base/nsAccessible.cpp b/accessible/src/base/nsAccessible.cpp index b19b5d4de0c3..d4ba4ce7aa7b 100644 --- a/accessible/src/base/nsAccessible.cpp +++ b/accessible/src/base/nsAccessible.cpp @@ -88,6 +88,7 @@ #include "nsIServiceManager.h" #include "nsWhitespaceTokenizer.h" #include "nsAttrName.h" +#include "nsNetUtil.h" #ifdef NS_DEBUG #include "nsIFrameDebug.h" @@ -1053,6 +1054,10 @@ nsAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState) if (frame && (frame->GetStateBits() & NS_FRAME_OUT_OF_FLOW)) *aState |= nsIAccessibleStates::STATE_FLOATING; + // Add 'linked' state for simple xlink. + if (nsAccUtils::IsXLink(content)) + *aState |= nsIAccessibleStates::STATE_LINKED; + return NS_OK; } @@ -2459,23 +2464,36 @@ nsAccessible::GetARIAState(PRUint32 *aState) // Not implemented by this class /* DOMString getValue (); */ -NS_IMETHODIMP nsAccessible::GetValue(nsAString& aValue) +NS_IMETHODIMP +nsAccessible::GetValue(nsAString& aValue) { - if (!mDOMNode) { - return NS_ERROR_FAILURE; // Node already shut down - } + if (IsDefunct()) + return NS_ERROR_FAILURE; + + nsCOMPtr content(do_QueryInterface(mDOMNode)); + if (mRoleMapEntry) { if (mRoleMapEntry->valueRule == eNoValue) { return NS_OK; } - nsCOMPtr content(do_QueryInterface(mDOMNode)); - NS_ENSURE_STATE(content); + // aria-valuenow is a number, and aria-valuetext is the optional text equivalent // For the string value, we will try the optional text equivalent first if (!content->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_valuetext, aValue)) { content->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_valuenow, aValue); } } + + if (!aValue.IsEmpty()) + return NS_OK; + + // Check if it's an simple xlink. + if (nsAccUtils::IsXLink(content)) { + nsCOMPtr presShell(do_QueryReferent(mWeakShell)); + if (presShell) + return presShell->GetLinkLocation(mDOMNode, aValue); + } + return NS_OK; } @@ -2579,6 +2597,14 @@ NS_IMETHODIMP nsAccessible::GetRole(PRUint32 *aRole) { NS_ENSURE_ARG_POINTER(aRole); *aRole = nsIAccessibleRole::ROLE_NOTHING; + + if (IsDefunct()) + return NS_ERROR_FAILURE; + + nsCOMPtr content(do_QueryInterface(mDOMNode)); + if (nsAccUtils::IsXLink(content)) + *aRole = nsIAccessibleRole::ROLE_LINK; + return NS_OK; } @@ -2592,7 +2618,14 @@ nsAccessible::GetNumActions(PRUint8 *aNumActions) if (IsDefunct()) return NS_ERROR_FAILURE; + // Check if it's an simple xlink. nsCOMPtr content(do_QueryInterface(mDOMNode)); + if (nsAccUtils::IsXLink(content)) { + *aNumActions = 1; + return NS_OK; + } + + // Has registered 'click' event handler. PRBool isOnclick = nsAccUtils::HasListener(content, NS_LITERAL_STRING("click")); @@ -2614,7 +2647,14 @@ nsAccessible::GetActionName(PRUint8 aIndex, nsAString& aName) if (IsDefunct()) return NS_ERROR_FAILURE; + // Check if it's simple xlink. nsCOMPtr content(do_QueryInterface(mDOMNode)); + if (nsAccUtils::IsXLink(content)) { + aName.AssignLiteral("jump"); + return NS_OK; + } + + // Has registered 'click' event handler. PRBool isOnclick = nsAccUtils::HasListener(content, NS_LITERAL_STRING("click")); @@ -2648,11 +2688,18 @@ nsAccessible::DoAction(PRUint8 aIndex) if (IsDefunct()) return NS_ERROR_FAILURE; + PRBool doAction = PR_FALSE; + + // Check if it's simple xlink. nsCOMPtr content(do_QueryInterface(mDOMNode)); - PRBool isOnclick = nsAccUtils::HasListener(content, - NS_LITERAL_STRING("click")); + if (nsAccUtils::IsXLink(content)) + doAction = PR_TRUE; + + // Has registered 'click' event handler. + if (!doAction) + doAction = nsAccUtils::HasListener(content, NS_LITERAL_STRING("click")); - if (isOnclick) + if (doAction) return DoCommand(content); return NS_ERROR_INVALID_ARG; @@ -3240,16 +3287,34 @@ nsAccessible::GetEndIndex(PRInt32 *aEndIndex) } NS_IMETHODIMP -nsAccessible::GetURI(PRInt32 i, nsIURI **aURI) +nsAccessible::GetURI(PRInt32 aIndex, nsIURI **aURI) { NS_ENSURE_ARG_POINTER(aURI); *aURI = nsnull; - return NS_ERROR_FAILURE; + + if (aIndex != 0) + return NS_ERROR_INVALID_ARG; + + // Check if it's simple xlink. + nsCOMPtr content(do_QueryInterface(mDOMNode)); + if (nsAccUtils::IsXLink(content)) { + nsAutoString href; + content->GetAttr(kNameSpaceID_XLink, nsAccessibilityAtoms::href, href); + + nsCOMPtr baseURI = content->GetBaseURI(); + nsCOMPtr document = content->GetOwnerDoc(); + return NS_NewURI(aURI, href, + document ? document->GetDocumentCharacterSet().get() : nsnull, + baseURI); + } + + return NS_OK; } + NS_IMETHODIMP nsAccessible::GetAnchor(PRInt32 aIndex, - nsIAccessible **aAccessible) + nsIAccessible **aAccessible) { NS_ENSURE_ARG_POINTER(aAccessible); *aAccessible = nsnull; diff --git a/accessible/src/xul/nsXULTextAccessible.cpp b/accessible/src/xul/nsXULTextAccessible.cpp index ff554d6c26c0..98d115f8e321 100644 --- a/accessible/src/xul/nsXULTextAccessible.cpp +++ b/accessible/src/xul/nsXULTextAccessible.cpp @@ -254,7 +254,9 @@ nsXULLinkAccessible::GetURI(PRInt32 aIndex, nsIURI **aURI) nsCOMPtr content(do_QueryInterface(mDOMNode)); content->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::href, href); + nsCOMPtr baseURI = content->GetBaseURI(); nsCOMPtr document = content->GetOwnerDoc(); return NS_NewURI(aURI, href, - document ? document->GetDocumentCharacterSet().get() : nsnull); + document ? document->GetDocumentCharacterSet().get() : nsnull, + baseURI); }