mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-23 12:51:06 +00:00
Bug 421066 - Implement all nsIAccessibleHyperLink methods for XUL:label elements that are used as links, r=ginn.chen, a=beltzner
This commit is contained in:
parent
fec1f1442c
commit
e4e19beac8
@ -21,6 +21,7 @@
|
||||
*
|
||||
* Contributor(s):
|
||||
* John Gaunt (jgaunt@netscape.com)
|
||||
* Alexander Surkov <surkov.alexander@gmail.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
@ -93,11 +94,11 @@ nsLeafAccessible::GetAllowsAnonChildAccessibles(PRBool *aAllowsAnonChildren)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//----------------
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsLinkableAccessible
|
||||
//----------------
|
||||
|
||||
nsLinkableAccessible::nsLinkableAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell) :
|
||||
nsLinkableAccessible::
|
||||
nsLinkableAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell) :
|
||||
nsHyperTextAccessibleWrap(aNode, aShell),
|
||||
mActionContent(nsnull),
|
||||
mIsLink(PR_FALSE),
|
||||
@ -107,74 +108,69 @@ nsLinkableAccessible::nsLinkableAccessible(nsIDOMNode* aNode, nsIWeakReference*
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED0(nsLinkableAccessible, nsHyperTextAccessibleWrap)
|
||||
|
||||
NS_IMETHODIMP nsLinkableAccessible::TakeFocus()
|
||||
{
|
||||
if (mActionContent && mActionContent->IsFocusable()) {
|
||||
nsCOMPtr<nsIDOMNSHTMLElement> htmlElement(do_QueryInterface(mActionContent));
|
||||
if (htmlElement) {
|
||||
// HTML Elements also set the caret position
|
||||
// in order to affect tabbing order
|
||||
return htmlElement->Focus();
|
||||
}
|
||||
NS_WARNING("Has action content that is not an HTML element");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsLinkableAccessible. nsIAccessible
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLinkableAccessible::TakeFocus()
|
||||
{
|
||||
nsCOMPtr<nsIAccessible> actionAcc = GetActionAccessible();
|
||||
if (actionAcc)
|
||||
return actionAcc->TakeFocus();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* long GetState (); */
|
||||
NS_IMETHODIMP
|
||||
nsLinkableAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
|
||||
{
|
||||
nsresult rv = nsHyperTextAccessibleWrap::GetState(aState, aExtraState);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (!mDOMNode)
|
||||
return NS_OK;
|
||||
|
||||
if (mIsLink) {
|
||||
*aState |= nsIAccessibleStates::STATE_LINKED;
|
||||
nsCOMPtr<nsILink> link = do_QueryInterface(mActionContent);
|
||||
if (link) {
|
||||
nsLinkState linkState;
|
||||
link->GetLinkState(linkState);
|
||||
if (linkState == eLinkState_Visited) {
|
||||
*aState |= nsIAccessibleStates::STATE_TRAVERSED;
|
||||
}
|
||||
}
|
||||
nsCOMPtr<nsIAccessible> actionAcc = GetActionAccessible();
|
||||
if (actionAcc && (State(actionAcc) & nsIAccessibleStates::STATE_TRAVERSED))
|
||||
*aState |= nsIAccessibleStates::STATE_TRAVERSED;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsLinkableAccessible::GetValue(nsAString& aValue)
|
||||
NS_IMETHODIMP
|
||||
nsLinkableAccessible::GetValue(nsAString& aValue)
|
||||
{
|
||||
aValue.Truncate();
|
||||
|
||||
nsHyperTextAccessible::GetValue(aValue);
|
||||
if (!aValue.IsEmpty())
|
||||
return NS_OK;
|
||||
|
||||
if (mIsLink) {
|
||||
nsCOMPtr<nsIDOMNode> linkNode(do_QueryInterface(mActionContent));
|
||||
nsCOMPtr<nsIPresShell> presShell(do_QueryReferent(mWeakShell));
|
||||
if (linkNode && presShell)
|
||||
return presShell->GetLinkLocation(linkNode, aValue);
|
||||
nsCOMPtr<nsIAccessible> actionAcc = GetActionAccessible();
|
||||
if (actionAcc)
|
||||
return actionAcc->GetValue(aValue);
|
||||
}
|
||||
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
/* PRUint8 getAccNumActions (); */
|
||||
NS_IMETHODIMP nsLinkableAccessible::GetNumActions(PRUint8 *aNumActions)
|
||||
NS_IMETHODIMP
|
||||
nsLinkableAccessible::GetNumActions(PRUint8 *aNumActions)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aNumActions);
|
||||
|
||||
*aNumActions = mActionContent ? 1 : 0;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* nsAString GetActionName (in PRUint8 Aindex); */
|
||||
NS_IMETHODIMP nsLinkableAccessible::GetActionName(PRUint8 aIndex, nsAString& aName)
|
||||
NS_IMETHODIMP
|
||||
nsLinkableAccessible::GetActionName(PRUint8 aIndex, nsAString& aName)
|
||||
{
|
||||
// Action 0 (default action): Jump to link
|
||||
aName.Truncate();
|
||||
|
||||
// Action 0 (default action): Jump to link
|
||||
if (aIndex == eAction_Jump) {
|
||||
if (mIsLink) {
|
||||
aName.AssignLiteral("jump");
|
||||
@ -189,105 +185,124 @@ NS_IMETHODIMP nsLinkableAccessible::GetActionName(PRUint8 aIndex, nsAString& aNa
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
/* void accDoAction (in PRUint8 index); */
|
||||
NS_IMETHODIMP nsLinkableAccessible::DoAction(PRUint8 index)
|
||||
NS_IMETHODIMP
|
||||
nsLinkableAccessible::DoAction(PRUint8 aIndex)
|
||||
{
|
||||
// Action 0 (default action): Jump to link
|
||||
if (index == eAction_Jump) {
|
||||
if (mActionContent) {
|
||||
return DoCommand(mActionContent);
|
||||
}
|
||||
}
|
||||
nsCOMPtr<nsIAccessible> actionAcc = GetActionAccessible();
|
||||
if (actionAcc)
|
||||
return actionAcc->DoAction(aIndex);
|
||||
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsLinkableAccessible::GetKeyboardShortcut(nsAString& aKeyboardShortcut)
|
||||
NS_IMETHODIMP
|
||||
nsLinkableAccessible::GetKeyboardShortcut(nsAString& aKeyboardShortcut)
|
||||
{
|
||||
if (mActionContent) {
|
||||
nsCOMPtr<nsIDOMNode> actionNode(do_QueryInterface(mActionContent));
|
||||
if (actionNode && mDOMNode != actionNode) {
|
||||
nsCOMPtr<nsIAccessible> accessible;
|
||||
nsCOMPtr<nsIAccessibilityService> accService =
|
||||
do_GetService("@mozilla.org/accessibilityService;1");
|
||||
accService->GetAccessibleInWeakShell(actionNode, mWeakShell,
|
||||
getter_AddRefs(accessible));
|
||||
if (accessible) {
|
||||
accessible->GetKeyboardShortcut(aKeyboardShortcut);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
aKeyboardShortcut.Truncate();
|
||||
|
||||
nsCOMPtr<nsIAccessible> actionAcc = GetActionAccessible();
|
||||
if (actionAcc)
|
||||
return actionAcc->GetKeyboardShortcut(aKeyboardShortcut);
|
||||
|
||||
return nsAccessible::GetKeyboardShortcut(aKeyboardShortcut);
|
||||
}
|
||||
|
||||
void nsLinkableAccessible::CacheActionContent()
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsLinkableAccessible. nsIAccessibleHyperLink
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLinkableAccessible::GetURI(PRInt32 aIndex, nsIURI **aURI)
|
||||
{
|
||||
for (nsCOMPtr<nsIContent> walkUpContent(do_QueryInterface(mDOMNode));
|
||||
walkUpContent;
|
||||
walkUpContent = walkUpContent->GetParent()) {
|
||||
PRBool isOnclick = nsAccUtils::HasListener(walkUpContent, NS_LITERAL_STRING("click"));
|
||||
nsIAtom *tag = walkUpContent->Tag();
|
||||
if ((tag == nsAccessibilityAtoms::a || tag == nsAccessibilityAtoms::area) &&
|
||||
walkUpContent->IsNodeOfType(nsINode::eHTML)) {
|
||||
nsCOMPtr<nsILink> link = do_QueryInterface(walkUpContent);
|
||||
if (link) {
|
||||
// Currently we do not expose <link> tags, because they are not typically
|
||||
// in <body> and rendered.
|
||||
// We do not yet support xlinks
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
link->GetHrefURI(getter_AddRefs(uri));
|
||||
if (uri) {
|
||||
mActionContent = walkUpContent;
|
||||
mIsLink = PR_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (SameCOMIdentity(mDOMNode, walkUpContent)) {
|
||||
// This is the element that caused the creation of a linkable accessible
|
||||
// Don't let it keep walking up, otherwise we may report the wrong container
|
||||
// as the action node
|
||||
mActionContent = walkUpContent;
|
||||
mIsOnclick = isOnclick;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isOnclick) {
|
||||
mActionContent = walkUpContent;
|
||||
mIsOnclick = PR_TRUE;
|
||||
break;
|
||||
if (mIsLink) {
|
||||
nsCOMPtr<nsIAccessible> actionAcc = GetActionAccessible();
|
||||
if (actionAcc) {
|
||||
nsCOMPtr<nsIAccessibleHyperLink> hyperLinkAcc =
|
||||
do_QueryInterface(actionAcc);
|
||||
NS_ASSERTION(hyperLinkAcc,
|
||||
"nsIAccessibleHyperLink isn't implemented.");
|
||||
|
||||
if (hyperLinkAcc)
|
||||
return hyperLinkAcc->GetURI(aIndex, aURI);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
// nsIAccessibleHyperLink::GetURI()
|
||||
NS_IMETHODIMP nsLinkableAccessible::GetURI(PRInt32 aIndex, nsIURI **aURI)
|
||||
{
|
||||
// XXX Also implement this for nsHTMLImageAccessible file names
|
||||
*aURI = nsnull;
|
||||
if (aIndex != 0 || !mIsLink || !SameCOMIdentity(mDOMNode, mActionContent)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsLinkableAccessible. nsPIAccessNode
|
||||
|
||||
nsCOMPtr<nsILink> link(do_QueryInterface(mActionContent));
|
||||
if (link) {
|
||||
return link->GetHrefURI(aURI);
|
||||
}
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsLinkableAccessible::Init()
|
||||
NS_IMETHODIMP
|
||||
nsLinkableAccessible::Init()
|
||||
{
|
||||
CacheActionContent();
|
||||
return nsHyperTextAccessibleWrap::Init();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsLinkableAccessible::Shutdown()
|
||||
NS_IMETHODIMP
|
||||
nsLinkableAccessible::Shutdown()
|
||||
{
|
||||
mActionContent = nsnull;
|
||||
return nsHyperTextAccessibleWrap::Shutdown();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsLinkableAccessible
|
||||
|
||||
void
|
||||
nsLinkableAccessible::CacheActionContent()
|
||||
{
|
||||
nsCOMPtr<nsIContent> walkUpContent(do_QueryInterface(mDOMNode));
|
||||
PRBool isOnclick = nsAccUtils::HasListener(walkUpContent,
|
||||
NS_LITERAL_STRING("click"));
|
||||
|
||||
if (isOnclick) {
|
||||
mActionContent = walkUpContent;
|
||||
mIsOnclick = PR_TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
while ((walkUpContent = walkUpContent->GetParent())) {
|
||||
isOnclick = nsAccUtils::HasListener(walkUpContent,
|
||||
NS_LITERAL_STRING("click"));
|
||||
|
||||
nsCOMPtr<nsIDOMNode> walkUpNode(do_QueryInterface(walkUpContent));
|
||||
|
||||
nsCOMPtr<nsIAccessible> walkUpAcc;
|
||||
GetAccService()->GetAccessibleInWeakShell(walkUpNode, mWeakShell,
|
||||
getter_AddRefs(walkUpAcc));
|
||||
|
||||
if (walkUpAcc && Role(walkUpAcc) == nsIAccessibleRole::ROLE_LINK) {
|
||||
mIsLink = PR_TRUE;
|
||||
mActionContent = walkUpContent;
|
||||
return;
|
||||
}
|
||||
|
||||
if (isOnclick) {
|
||||
mActionContent = walkUpContent;
|
||||
mIsOnclick = PR_TRUE;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
already_AddRefed<nsIAccessible>
|
||||
nsLinkableAccessible::GetActionAccessible()
|
||||
{
|
||||
// Return accessible for the action content if it's different from node of
|
||||
// this accessible. If the action accessible is not null then it is used to
|
||||
// redirect methods calls otherwise we use method implementation from the
|
||||
// base class.
|
||||
nsCOMPtr<nsIDOMNode> actionNode(do_QueryInterface(mActionContent));
|
||||
if (!actionNode || mDOMNode == actionNode)
|
||||
return nsnull;
|
||||
|
||||
nsIAccessible *accessible = nsnull;
|
||||
GetAccService()->GetAccessibleInWeakShell(actionNode, mWeakShell,
|
||||
&accessible);
|
||||
return accessible;
|
||||
}
|
||||
|
||||
//---------------------
|
||||
// nsEnumRoleAccessible
|
||||
//---------------------
|
||||
|
@ -78,7 +78,10 @@ public:
|
||||
enum { eAction_Jump = 0 };
|
||||
|
||||
nsLinkableAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell);
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
// nsIAccessible
|
||||
NS_IMETHOD GetNumActions(PRUint8 *_retval);
|
||||
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
|
||||
NS_IMETHOD DoAction(PRUint8 index);
|
||||
@ -86,12 +89,25 @@ public:
|
||||
NS_IMETHOD GetValue(nsAString& _retval);
|
||||
NS_IMETHOD TakeFocus();
|
||||
NS_IMETHOD GetKeyboardShortcut(nsAString& _retval);
|
||||
|
||||
// nsIHyperLinkAccessible
|
||||
NS_IMETHOD GetURI(PRInt32 i, nsIURI **aURI);
|
||||
|
||||
// nsPIAccessNode
|
||||
NS_IMETHOD Init();
|
||||
NS_IMETHOD Shutdown();
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Return an accessible for cached action node.
|
||||
*/
|
||||
already_AddRefed<nsIAccessible> GetActionAccessible();
|
||||
|
||||
/**
|
||||
* Cache action node.
|
||||
*/
|
||||
virtual void CacheActionContent();
|
||||
|
||||
nsCOMPtr<nsIContent> mActionContent;
|
||||
PRPackedBool mIsLink;
|
||||
PRPackedBool mIsOnclick;
|
||||
|
@ -37,7 +37,6 @@
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsHTMLAreaAccessible.h"
|
||||
#include "nsIAccessibilityService.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsIDOMHTMLAreaElement.h"
|
||||
@ -46,32 +45,36 @@
|
||||
#include "nsIImageMap.h"
|
||||
|
||||
|
||||
// --- area -----
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsHTMLAreaAccessible
|
||||
|
||||
nsHTMLAreaAccessible::nsHTMLAreaAccessible(nsIDOMNode *aDomNode, nsIAccessible *aParent, nsIWeakReference* aShell):
|
||||
nsLinkableAccessible(aDomNode, aShell)
|
||||
nsHTMLAreaAccessible::
|
||||
nsHTMLAreaAccessible(nsIDOMNode *aDomNode, nsIAccessible *aParent,
|
||||
nsIWeakReference* aShell):
|
||||
nsHTMLLinkAccessible(aDomNode, aShell)
|
||||
{
|
||||
}
|
||||
|
||||
// Expose nsIAccessibleHyperLink unconditionally
|
||||
NS_IMPL_ISUPPORTS_INHERITED1(nsHTMLAreaAccessible, nsLinkableAccessible,
|
||||
nsIAccessibleHyperLink)
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsIAccessible
|
||||
|
||||
/* wstring getName (); */
|
||||
NS_IMETHODIMP nsHTMLAreaAccessible::GetName(nsAString & aName)
|
||||
NS_IMETHODIMP
|
||||
nsHTMLAreaAccessible::GetName(nsAString & aName)
|
||||
{
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
|
||||
if (!content) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
aName.Truncate();
|
||||
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if (mRoleMapEntry) {
|
||||
nsresult rv = nsAccessible::GetName(aName);
|
||||
if (!aName.IsEmpty()) {
|
||||
return rv;
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!aName.IsEmpty())
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
|
||||
if (!content->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::alt,
|
||||
aName) &&
|
||||
!content->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::title,
|
||||
@ -82,47 +85,49 @@ NS_IMETHODIMP nsHTMLAreaAccessible::GetName(nsAString & aName)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* unsigned long getRole (); */
|
||||
NS_IMETHODIMP nsHTMLAreaAccessible::GetRole(PRUint32 *_retval)
|
||||
NS_IMETHODIMP
|
||||
nsHTMLAreaAccessible::GetDescription(nsAString& aDescription)
|
||||
{
|
||||
*_retval = nsIAccessibleRole::ROLE_LINK;
|
||||
return NS_OK;
|
||||
}
|
||||
aDescription.Truncate();
|
||||
|
||||
/* wstring getDescription (); */
|
||||
NS_IMETHODIMP nsHTMLAreaAccessible::GetDescription(nsAString& _retval)
|
||||
{
|
||||
// Still to do - follow IE's standard here
|
||||
nsCOMPtr<nsIDOMHTMLAreaElement> area(do_QueryInterface(mDOMNode));
|
||||
if (area)
|
||||
area->GetShape(_retval);
|
||||
area->GetShape(aDescription);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
/* nsIAccessible getFirstChild (); */
|
||||
NS_IMETHODIMP nsHTMLAreaAccessible::GetFirstChild(nsIAccessible **_retval)
|
||||
NS_IMETHODIMP
|
||||
nsHTMLAreaAccessible::GetFirstChild(nsIAccessible **aChild)
|
||||
{
|
||||
*_retval = nsnull;
|
||||
NS_ENSURE_ARG_POINTER(aChild);
|
||||
|
||||
*aChild = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* nsIAccessible getLastChild (); */
|
||||
NS_IMETHODIMP nsHTMLAreaAccessible::GetLastChild(nsIAccessible **_retval)
|
||||
NS_IMETHODIMP
|
||||
nsHTMLAreaAccessible::GetLastChild(nsIAccessible **aChild)
|
||||
{
|
||||
*_retval = nsnull;
|
||||
NS_ENSURE_ARG_POINTER(aChild);
|
||||
|
||||
*aChild = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* long getAccChildCount (); */
|
||||
NS_IMETHODIMP nsHTMLAreaAccessible::GetChildCount(PRInt32 *_retval)
|
||||
NS_IMETHODIMP
|
||||
nsHTMLAreaAccessible::GetChildCount(PRInt32 *aCount)
|
||||
{
|
||||
*_retval = 0;
|
||||
NS_ENSURE_ARG_POINTER(aCount);
|
||||
|
||||
*aCount = 0;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void accGetBounds (out long x, out long y, out long width, out long height); */
|
||||
NS_IMETHODIMP nsHTMLAreaAccessible::GetBounds(PRInt32 *x, PRInt32 *y, PRInt32 *width, PRInt32 *height)
|
||||
NS_IMETHODIMP
|
||||
nsHTMLAreaAccessible::GetBounds(PRInt32 *x, PRInt32 *y,
|
||||
PRInt32 *width, PRInt32 *height)
|
||||
{
|
||||
// Essentially this uses GetRect on mAreas of nsImageMap from nsImageFrame
|
||||
|
||||
|
@ -39,27 +39,26 @@
|
||||
#ifndef _nsHTMLAreaAccessible_H_
|
||||
#define _nsHTMLAreaAccessible_H_
|
||||
|
||||
#include "nsBaseWidgetAccessible.h"
|
||||
#include "nsHTMLLinkAccessible.h"
|
||||
|
||||
/* Accessible for image map areas - must be child of image
|
||||
*/
|
||||
|
||||
class nsHTMLAreaAccessible : public nsLinkableAccessible
|
||||
class nsHTMLAreaAccessible : public nsHTMLLinkAccessible
|
||||
{
|
||||
|
||||
public:
|
||||
nsHTMLAreaAccessible(nsIDOMNode *domNode, nsIAccessible *accParent,
|
||||
nsIWeakReference* aShell);
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
// nsIAccessible
|
||||
NS_IMETHOD GetName(nsAString & _retval);
|
||||
NS_IMETHOD GetRole(PRUint32 *_retval);
|
||||
NS_IMETHOD GetName(nsAString & aName);
|
||||
NS_IMETHOD GetDescription(nsAString& aDescription);
|
||||
|
||||
NS_IMETHOD GetFirstChild(nsIAccessible **_retval);
|
||||
NS_IMETHOD GetLastChild(nsIAccessible **_retval);
|
||||
NS_IMETHOD GetChildCount(PRInt32 *_retval);
|
||||
NS_IMETHOD GetDescription(nsAString& _retval);
|
||||
|
||||
NS_IMETHOD GetBounds(PRInt32 *x, PRInt32 *y, PRInt32 *width, PRInt32 *height);
|
||||
NS_IMETHOD GetChildAtPoint(PRInt32 aX, PRInt32 aY, nsIAccessible **aAccessible)
|
||||
{ NS_ENSURE_ARG_POINTER(aAccessible); NS_ADDREF(*aAccessible = this); return NS_OK; } // Don't walk into these
|
||||
|
@ -20,7 +20,8 @@
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Author: Aaron Leventhal (aaronl@netscape.com)
|
||||
* Aaron Leventhal <aleventh@us.ibm.com> (original author)
|
||||
* Alexander Surkov <surkov.alexander@gmail.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
@ -37,38 +38,50 @@
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsHTMLLinkAccessible.h"
|
||||
#include "nsAccessibilityAtoms.h"
|
||||
#include "nsIAccessibleEvent.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED0(nsHTMLLinkAccessible, nsLinkableAccessible)
|
||||
#include "nsILink.h"
|
||||
|
||||
nsHTMLLinkAccessible::nsHTMLLinkAccessible(nsIDOMNode* aDomNode, nsIWeakReference* aShell):
|
||||
nsLinkableAccessible(aDomNode, aShell)
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsHTMLLinkAccessible
|
||||
|
||||
nsHTMLLinkAccessible::nsHTMLLinkAccessible(nsIDOMNode* aDomNode,
|
||||
nsIWeakReference* aShell):
|
||||
nsHyperTextAccessibleWrap(aDomNode, aShell)
|
||||
{
|
||||
}
|
||||
|
||||
/* wstring getName (); */
|
||||
NS_IMETHODIMP nsHTMLLinkAccessible::GetName(nsAString& aName)
|
||||
// Expose nsIAccessibleHyperLink unconditionally
|
||||
NS_IMPL_ISUPPORTS_INHERITED1(nsHTMLLinkAccessible, nsHyperTextAccessibleWrap,
|
||||
nsIAccessibleHyperLink)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsIAccessible
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLLinkAccessible::GetName(nsAString& aName)
|
||||
{
|
||||
if (!mActionContent)
|
||||
aName.Truncate();
|
||||
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
return AppendFlatStringFromSubtree(mActionContent, &aName);
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
|
||||
return AppendFlatStringFromSubtree(content, &aName);
|
||||
}
|
||||
|
||||
/* unsigned long getRole (); */
|
||||
NS_IMETHODIMP nsHTMLLinkAccessible::GetRole(PRUint32 *_retval)
|
||||
NS_IMETHODIMP
|
||||
nsHTMLLinkAccessible::GetRole(PRUint32 *aRole)
|
||||
{
|
||||
*_retval = nsIAccessibleRole::ROLE_LINK;
|
||||
NS_ENSURE_ARG_POINTER(aRole);
|
||||
|
||||
*aRole = nsIAccessibleRole::ROLE_LINK;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLLinkAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
|
||||
{
|
||||
nsresult rv = nsLinkableAccessible::GetState(aState, aExtraState);
|
||||
nsresult rv = nsHyperTextAccessibleWrap::GetState(aState, aExtraState);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (!mDOMNode)
|
||||
return NS_OK;
|
||||
@ -84,5 +97,85 @@ nsHTMLLinkAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
|
||||
*aState |= nsIAccessibleStates::STATE_SELECTABLE;
|
||||
}
|
||||
|
||||
*aState |= nsIAccessibleStates::STATE_LINKED;
|
||||
nsCOMPtr<nsILink> link = do_QueryInterface(mDOMNode);
|
||||
NS_ENSURE_STATE(link);
|
||||
|
||||
nsLinkState linkState;
|
||||
link->GetLinkState(linkState);
|
||||
if (linkState == eLinkState_Visited)
|
||||
*aState |= nsIAccessibleStates::STATE_TRAVERSED;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLLinkAccessible::GetValue(nsAString& aValue)
|
||||
{
|
||||
aValue.Truncate();
|
||||
|
||||
nsresult rv = nsHyperTextAccessible::GetValue(aValue);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!aValue.IsEmpty())
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIPresShell> presShell(do_QueryReferent(mWeakShell));
|
||||
if (mDOMNode && presShell)
|
||||
return presShell->GetLinkLocation(mDOMNode, aValue);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLLinkAccessible::GetNumActions(PRUint8 *aNumActions)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aNumActions);
|
||||
|
||||
*aNumActions = 1;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLLinkAccessible::GetActionName(PRUint8 aIndex, nsAString& aName)
|
||||
{
|
||||
// Action 0 (default action): Jump to link
|
||||
aName.Truncate();
|
||||
if (aIndex != eAction_Jump)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
aName.AssignLiteral("jump");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLLinkAccessible::DoAction(PRUint8 aIndex)
|
||||
{
|
||||
// Action 0 (default action): Jump to link
|
||||
if (aIndex != eAction_Jump)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
|
||||
return DoCommand(content);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsIAccessibleHyperLink
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLLinkAccessible::GetURI(PRInt32 aIndex, nsIURI **aURI)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aURI);
|
||||
*aURI = nsnull;
|
||||
|
||||
if (aIndex != 0)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
nsCOMPtr<nsILink> link(do_QueryInterface(mDOMNode));
|
||||
NS_ENSURE_STATE(link);
|
||||
|
||||
return link->GetHrefURI(aURI);
|
||||
}
|
||||
|
@ -20,7 +20,8 @@
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Author: Aaron Leventhal (aaronl@netscape.com)
|
||||
* Aaron Leventhal <aleventh@us.ibm.com> (original author)
|
||||
* Alexander Surkov <surkov.alexander@gmail.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
@ -39,19 +40,30 @@
|
||||
#ifndef _nsHTMLLinkAccessible_H_
|
||||
#define _nsHTMLLinkAccessible_H_
|
||||
|
||||
#include "nsBaseWidgetAccessible.h"
|
||||
#include "nsHyperTextAccessibleWrap.h"
|
||||
|
||||
class nsHTMLLinkAccessible : public nsLinkableAccessible
|
||||
class nsHTMLLinkAccessible : public nsHyperTextAccessibleWrap
|
||||
{
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
public:
|
||||
nsHTMLLinkAccessible(nsIDOMNode* aDomNode, nsIWeakReference* aShell);
|
||||
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
// nsIAccessible
|
||||
NS_IMETHOD GetName(nsAString& _retval);
|
||||
NS_IMETHOD GetRole(PRUint32 *_retval);
|
||||
NS_IMETHOD GetName(nsAString& aName);
|
||||
NS_IMETHOD GetRole(PRUint32 *aRole);
|
||||
NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
|
||||
NS_IMETHOD GetValue(nsAString& aValue);
|
||||
|
||||
NS_IMETHOD GetNumActions(PRUint8 *aNumActions);
|
||||
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
|
||||
NS_IMETHOD DoAction(PRUint8 aIndex);
|
||||
|
||||
// nsIAccessibleHyperLink
|
||||
NS_IMETHOD GetURI(PRInt32 aIndex, nsIURI **aURI);
|
||||
|
||||
protected:
|
||||
enum { eAction_Jump = 0 };
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -45,6 +45,7 @@
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsString.h"
|
||||
#include "nsXULTextAccessible.h"
|
||||
#include "nsNetUtil.h"
|
||||
|
||||
/**
|
||||
* For XUL descriptions and labels
|
||||
@ -138,62 +139,118 @@ NS_IMETHODIMP nsXULTooltipAccessible::GetRole(PRUint32 *_retval)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* For XUL text links
|
||||
*/
|
||||
nsXULLinkAccessible::nsXULLinkAccessible(nsIDOMNode *aDomNode, nsIWeakReference *aShell):
|
||||
nsLinkableAccessible(aDomNode, aShell)
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsXULLinkAccessible
|
||||
|
||||
nsXULLinkAccessible::
|
||||
nsXULLinkAccessible(nsIDOMNode *aDomNode, nsIWeakReference *aShell):
|
||||
nsHyperTextAccessibleWrap(aDomNode, aShell)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsXULLinkAccessible::GetValue(nsAString& aValue)
|
||||
{
|
||||
if (mIsLink) {
|
||||
mActionContent->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::href, aValue);
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsXULLinkAccessible. nsIAccessible
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULLinkAccessible::GetValue(nsAString& aValue)
|
||||
{
|
||||
aValue.Truncate();
|
||||
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
NS_IMETHODIMP nsXULLinkAccessible::GetName(nsAString& aName)
|
||||
{
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
|
||||
if (!content) {
|
||||
return NS_ERROR_FAILURE; // Node shut down
|
||||
}
|
||||
if (!content->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::value,
|
||||
aName)) {
|
||||
// if the value doesn't exist, flatten the inner content as the name (for descriptions)
|
||||
return AppendFlatStringFromSubtree(content, &aName);
|
||||
}
|
||||
// otherwise, use the value attribute as the name (for labels)
|
||||
content->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::href, aValue);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsXULLinkAccessible::GetRole(PRUint32 *aRole)
|
||||
NS_IMETHODIMP
|
||||
nsXULLinkAccessible::GetName(nsAString& aName)
|
||||
{
|
||||
// We used to say ROLE_BUTTON if there was no href, but then screen readers
|
||||
// would tell users to hit the space bar for activation, which is wrong for a link
|
||||
aName.Truncate();
|
||||
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
|
||||
content->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::value, aName);
|
||||
if (!aName.IsEmpty())
|
||||
return NS_OK;
|
||||
|
||||
return AppendFlatStringFromSubtree(content, &aName);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULLinkAccessible::GetRole(PRUint32 *aRole)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aRole);
|
||||
|
||||
*aRole = nsIAccessibleRole::ROLE_LINK;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void nsXULLinkAccessible::CacheActionContent()
|
||||
{
|
||||
// not a link if no content
|
||||
nsCOMPtr<nsIContent> mTempContent = do_QueryInterface(mDOMNode);
|
||||
if (!mTempContent) {
|
||||
return;
|
||||
}
|
||||
|
||||
// not a link if there is no href attribute or not on a <link> tag
|
||||
if (mTempContent->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::href) ||
|
||||
mTempContent->Tag() == nsAccessibilityAtoms::link) {
|
||||
mIsLink = PR_TRUE;
|
||||
mActionContent = mTempContent;
|
||||
}
|
||||
else if (nsAccUtils::HasListener(mTempContent, NS_LITERAL_STRING("click"))) {
|
||||
mIsOnclick = PR_TRUE;
|
||||
mActionContent = mTempContent;
|
||||
}
|
||||
NS_IMETHODIMP
|
||||
nsXULLinkAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
|
||||
{
|
||||
nsresult rv = nsHyperTextAccessibleWrap::GetState(aState, aExtraState);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
*aState |= nsIAccessibleStates::STATE_LINKED;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULLinkAccessible::GetNumActions(PRUint8 *aNumActions)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aNumActions);
|
||||
|
||||
*aNumActions = 1;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULLinkAccessible::GetActionName(PRUint8 aIndex, nsAString& aName)
|
||||
{
|
||||
aName.Truncate();
|
||||
|
||||
if (aIndex != eAction_Jump)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
aName.AssignLiteral("jump");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULLinkAccessible::DoAction(PRUint8 aIndex)
|
||||
{
|
||||
if (aIndex != eAction_Jump)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
|
||||
return DoCommand(content);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsXULLinkAccessible. nsIAccessibleHyperLink
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULLinkAccessible::GetURI(PRInt32 aIndex, nsIURI **aURI)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aURI);
|
||||
*aURI = nsnull;
|
||||
|
||||
if (aIndex != 0)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
nsAutoString href;
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
|
||||
content->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::href, href);
|
||||
|
||||
nsCOMPtr<nsIDocument> document = content->GetOwnerDoc();
|
||||
return NS_NewURI(aURI, href,
|
||||
document ? document->GetDocumentCharacterSet().get() : nsnull);
|
||||
}
|
||||
|
@ -68,17 +68,28 @@ public:
|
||||
NS_IMETHOD GetRole(PRUint32 *_retval);
|
||||
};
|
||||
|
||||
class nsXULLinkAccessible : public nsLinkableAccessible
|
||||
class nsXULLinkAccessible : public nsHyperTextAccessibleWrap
|
||||
{
|
||||
|
||||
public:
|
||||
nsXULLinkAccessible(nsIDOMNode* aDomNode, nsIWeakReference* aShell);
|
||||
NS_IMETHOD GetName(nsAString& _retval);
|
||||
|
||||
// nsIAccessible
|
||||
NS_IMETHOD GetName(nsAString& aName);
|
||||
NS_IMETHOD GetRole(PRUint32 *aRole);
|
||||
NS_IMETHOD GetValue(nsAString& _retval);
|
||||
NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
|
||||
NS_IMETHOD GetValue(nsAString& aValue);
|
||||
|
||||
NS_IMETHOD GetNumActions(PRUint8 *aNumActions);
|
||||
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
|
||||
NS_IMETHOD DoAction(PRUint8 aIndex);
|
||||
|
||||
// nsIAccessibleHyperLink
|
||||
NS_IMETHOD GetURI(PRInt32 aIndex, nsIURI **aURI);
|
||||
|
||||
protected:
|
||||
void CacheActionContent();
|
||||
enum { eAction_Jump = 0 };
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user