Bug 589399 - add pseudo HyperLinkAccessible interface, r=davidb, f=neil, a=davidb

--HG--
rename : accessible/tests/mochitest/test_nsIAccessibleHyperLink.html => accessible/tests/mochitest/hyperlink/test_general.html
rename : accessible/tests/mochitest/test_nsIAccessibleHyperLink.xul => accessible/tests/mochitest/hyperlink/test_general.xul
This commit is contained in:
Alexander Surkov 2010-09-01 12:26:13 +09:00
parent a335682adb
commit 250583af1b
19 changed files with 436 additions and 275 deletions

View File

@ -452,11 +452,8 @@ nsAccessibleWrap::CreateMaiInterfaces(void)
interfacesBits |= 1 << MAI_INTERFACE_IMAGE;
}
//nsIAccessibleHyperLink
nsCOMPtr<nsIAccessibleHyperLink> accessInterfaceHyperlink;
QueryInterface(NS_GET_IID(nsIAccessibleHyperLink),
getter_AddRefs(accessInterfaceHyperlink));
if (accessInterfaceHyperlink) {
// HyperLinkAccessible
if (IsHyperLink()) {
interfacesBits |= 1 << MAI_INTERFACE_HYPERLINK_IMPL;
}

View File

@ -93,7 +93,7 @@ static gint getAnchorCountCB(AtkHyperlink *aLink);
G_END_DECLS
static gpointer parent_class = NULL;
static nsIAccessibleHyperLink *
static nsAccessible*
get_accessible_hyperlink(AtkHyperlink *aHyperlink);
GType
@ -122,8 +122,8 @@ mai_atk_hyperlink_get_type(void)
return type;
}
MaiHyperlink::MaiHyperlink(nsIAccessibleHyperLink *aAcc):
mHyperlink(aAcc),
MaiHyperlink::MaiHyperlink(nsAccessible* aHyperLink) :
mHyperlink(aHyperLink),
mMaiAtkHyperlink(nsnull)
{
}
@ -144,8 +144,7 @@ MaiHyperlink::GetAtkHyperlink(void)
if (mMaiAtkHyperlink)
return mMaiAtkHyperlink;
nsCOMPtr<nsIAccessibleHyperLink> accessIf(do_QueryInterface(mHyperlink));
if (!accessIf)
if (!mHyperlink->IsHyperLink())
return nsnull;
mMaiAtkHyperlink =
@ -214,17 +213,18 @@ finalizeCB(GObject *aObj)
gchar *
getUriCB(AtkHyperlink *aLink, gint aLinkIndex)
{
nsIAccessibleHyperLink *accHyperlink = get_accessible_hyperlink(aLink);
NS_ENSURE_TRUE(accHyperlink, nsnull);
nsAccessible* hyperlink = get_accessible_hyperlink(aLink);
NS_ENSURE_TRUE(hyperlink, nsnull);
MaiAtkHyperlink *maiAtkHyperlink = MAI_ATK_HYPERLINK(aLink);
nsCOMPtr<nsIURI> uri;
nsresult rv = accHyperlink->GetURI(aLinkIndex,getter_AddRefs(uri));
if (NS_FAILED(rv) || !uri)
nsCOMPtr<nsIURI> uri = hyperlink->GetAnchorURI(aLinkIndex);
if (!uri)
return nsnull;
nsCAutoString cautoStr;
rv = uri->GetSpec(cautoStr);
nsresult rv = uri->GetSpec(cautoStr);
NS_ENSURE_SUCCESS(rv, nsnull);
return g_strdup(cautoStr.get());
}
@ -232,14 +232,13 @@ getUriCB(AtkHyperlink *aLink, gint aLinkIndex)
AtkObject *
getObjectCB(AtkHyperlink *aLink, gint aLinkIndex)
{
nsIAccessibleHyperLink *accHyperlink = get_accessible_hyperlink(aLink);
NS_ENSURE_TRUE(accHyperlink, nsnull);
nsAccessible* hyperlink = get_accessible_hyperlink(aLink);
NS_ENSURE_TRUE(hyperlink, nsnull);
nsCOMPtr<nsIAccessible> accObj;
accHyperlink->GetAnchor(aLinkIndex, getter_AddRefs(accObj));
NS_ENSURE_TRUE(accObj, nsnull);
nsAccessible* anchor = hyperlink->GetAnchor(aLinkIndex);
NS_ENSURE_TRUE(anchor, nsnull);
AtkObject *atkObj = nsAccessibleWrap::GetAtkObject(accObj);
AtkObject *atkObj = nsAccessibleWrap::GetAtkObject(anchor);
//no need to add ref it, because it is "get" not "ref"
return atkObj;
}
@ -247,52 +246,42 @@ getObjectCB(AtkHyperlink *aLink, gint aLinkIndex)
gint
getEndIndexCB(AtkHyperlink *aLink)
{
nsIAccessibleHyperLink *accHyperlink = get_accessible_hyperlink(aLink);
NS_ENSURE_TRUE(accHyperlink, -1);
nsAccessible* hyperlink = get_accessible_hyperlink(aLink);
NS_ENSURE_TRUE(hyperlink, -1);
PRInt32 endIndex = -1;
nsresult rv = accHyperlink->GetEndIndex(&endIndex);
return (NS_FAILED(rv)) ? -1 : static_cast<gint>(endIndex);
return static_cast<gint>(hyperlink->EndOffset());
}
gint
getStartIndexCB(AtkHyperlink *aLink)
{
nsIAccessibleHyperLink *accHyperlink = get_accessible_hyperlink(aLink);
NS_ENSURE_TRUE(accHyperlink, -1);
nsAccessible* hyperlink = get_accessible_hyperlink(aLink);
NS_ENSURE_TRUE(hyperlink, -1);
PRInt32 startIndex = -1;
nsresult rv = accHyperlink->GetStartIndex(&startIndex);
return (NS_FAILED(rv)) ? -1 : static_cast<gint>(startIndex);
return static_cast<gint>(hyperlink->StartOffset());
}
gboolean
isValidCB(AtkHyperlink *aLink)
{
nsIAccessibleHyperLink *accHyperlink = get_accessible_hyperlink(aLink);
NS_ENSURE_TRUE(accHyperlink, FALSE);
nsAccessible* hyperlink = get_accessible_hyperlink(aLink);
NS_ENSURE_TRUE(hyperlink, FALSE);
PRBool isValid = PR_FALSE;
nsresult rv = accHyperlink->GetValid(&isValid);
return (NS_FAILED(rv)) ? FALSE : static_cast<gboolean>(isValid);
return static_cast<gboolean>(hyperlink->IsValid());
}
gint
getAnchorCountCB(AtkHyperlink *aLink)
{
nsIAccessibleHyperLink *accHyperlink = get_accessible_hyperlink(aLink);
NS_ENSURE_TRUE(accHyperlink, -1);
nsAccessible* hyperlink = get_accessible_hyperlink(aLink);
NS_ENSURE_TRUE(hyperlink, -1);
PRInt32 count = -1;
nsresult rv = accHyperlink->GetAnchorCount(&count);
return (NS_FAILED(rv)) ? -1 : static_cast<gint>(count);
return static_cast<gint>(hyperlink->AnchorCount());
}
// Check if aHyperlink is a valid MaiHyperlink, and return the
// nsIAccessibleHyperLink related.
nsIAccessibleHyperLink *
// HyperLinkAccessible related.
nsAccessible*
get_accessible_hyperlink(AtkHyperlink *aHyperlink)
{
NS_ENSURE_TRUE(MAI_IS_ATK_HYPERLINK(aHyperlink), nsnull);

View File

@ -42,7 +42,7 @@
#define __MAI_HYPERLINK_H__
#include "nsMai.h"
#include "nsIAccessibleHyperLink.h"
#include "nsAccessible.h"
struct _AtkHyperlink;
typedef struct _AtkHyperlink AtkHyperlink;
@ -54,17 +54,17 @@ typedef struct _AtkHyperlink AtkHyperlink;
class MaiHyperlink
{
public:
MaiHyperlink(nsIAccessibleHyperLink *aAcc);
MaiHyperlink(nsAccessible* aHyperLink);
~MaiHyperlink();
public:
AtkHyperlink *GetAtkHyperlink(void);
nsIAccessibleHyperLink *GetAccHyperlink(void) {
return mHyperlink;
nsAccessible* GetAccHyperlink(void) {
return mHyperlink && mHyperlink->IsHyperLink() ? mHyperlink : nsnull;
}
protected:
nsIAccessibleHyperLink *mHyperlink;
nsAccessible* mHyperlink;
AtkHyperlink *mMaiAtkHyperlink;
public:
static nsresult Initialize(AtkHyperlink *aObj, MaiHyperlink *aClass);

View File

@ -56,11 +56,8 @@ getHyperlinkCB(AtkHyperlinkImpl *aImpl)
if (!accWrap)
return nsnull;
nsCOMPtr<nsIAccessibleHyperLink> accHyperlink;
accWrap->QueryInterface(NS_GET_IID(nsIAccessibleHyperLink),
getter_AddRefs(accHyperlink));
NS_ENSURE_TRUE(accHyperlink, nsnull);
NS_ENSURE_TRUE(accWrap->IsHyperLink(), nsnull);
MaiHyperlink *maiHyperlink = accWrap->GetMaiHyperlink();
NS_ENSURE_TRUE(maiHyperlink, nsnull);
return maiHyperlink->GetAtkHyperlink();

View File

@ -180,10 +180,7 @@ nsresult nsAccessible::QueryInterface(REFNSIID aIID, void** aInstancePtr)
}
if (aIID.Equals(NS_GET_IID(nsIAccessibleHyperLink))) {
// Every embedded accessible within hypertext accessible implements
// hyperlink interface.
nsCOMPtr<nsIAccessibleHyperText> hyperTextParent = do_QueryObject(GetParent());
if (hyperTextParent && nsAccUtils::IsEmbeddedObject(this)) {
if (IsHyperLink()) {
*aInstancePtr = static_cast<nsIAccessibleHyperLink*>(this);
NS_ADDREF_THIS();
return NS_OK;
@ -2525,7 +2522,12 @@ NS_IMETHODIMP
nsAccessible::GetAnchorCount(PRInt32 *aAnchorCount)
{
NS_ENSURE_ARG_POINTER(aAnchorCount);
*aAnchorCount = 1;
*aAnchorCount = 0;
if (IsDefunct())
return NS_ERROR_FAILURE;
*aAnchorCount = AnchorCount();
return NS_OK;
}
@ -2539,8 +2541,8 @@ nsAccessible::GetStartIndex(PRInt32 *aStartIndex)
if (IsDefunct())
return NS_ERROR_FAILURE;
PRInt32 endIndex;
return GetLinkOffset(aStartIndex, &endIndex);
*aStartIndex = StartOffset();
return NS_OK;
}
// readonly attribute long nsIAccessibleHyperLink::endIndex
@ -2553,47 +2555,39 @@ nsAccessible::GetEndIndex(PRInt32 *aEndIndex)
if (IsDefunct())
return NS_ERROR_FAILURE;
PRInt32 startIndex;
return GetLinkOffset(&startIndex, aEndIndex);
*aEndIndex = EndOffset();
return NS_OK;
}
NS_IMETHODIMP
nsAccessible::GetURI(PRInt32 aIndex, nsIURI **aURI)
{
NS_ENSURE_ARG_POINTER(aURI);
*aURI = nsnull;
if (aIndex != 0)
if (IsDefunct())
return NS_ERROR_FAILURE;
if (aIndex < 0 || aIndex >= static_cast<PRInt32>(AnchorCount()))
return NS_ERROR_INVALID_ARG;
// Check if it's a simple xlink.
if (nsCoreUtils::IsXLink(mContent)) {
nsAutoString href;
mContent->GetAttr(kNameSpaceID_XLink, nsAccessibilityAtoms::href, href);
nsCOMPtr<nsIURI> baseURI = mContent->GetBaseURI();
nsCOMPtr<nsIDocument> document = mContent->GetOwnerDoc();
return NS_NewURI(aURI, href,
document ? document->GetDocumentCharacterSet().get() : nsnull,
baseURI);
}
*aURI = GetAnchorURI(aIndex).get();
return NS_OK;
}
NS_IMETHODIMP
nsAccessible::GetAnchor(PRInt32 aIndex,
nsIAccessible **aAccessible)
nsAccessible::GetAnchor(PRInt32 aIndex, nsIAccessible** aAccessible)
{
NS_ENSURE_ARG_POINTER(aAccessible);
*aAccessible = nsnull;
if (aIndex != 0)
if (IsDefunct())
return NS_ERROR_FAILURE;
if (aIndex < 0 || aIndex >= static_cast<PRInt32>(AnchorCount()))
return NS_ERROR_INVALID_ARG;
*aAccessible = this;
NS_ADDREF_THIS();
NS_IF_ADDREF(*aAccessible = GetAnchor(aIndex));
return NS_OK;
}
@ -2602,12 +2596,12 @@ NS_IMETHODIMP
nsAccessible::GetValid(PRBool *aValid)
{
NS_ENSURE_ARG_POINTER(aValid);
PRUint32 state = nsAccUtils::State(this);
*aValid = (0 == (state & nsIAccessibleStates::STATE_INVALID));
// XXX In order to implement this we would need to follow every link
// Perhaps we can get information about invalid links from the cache
// In the mean time authors can use role="link" aria-invalid="true"
// to force it for links they internally know to be invalid
*aValid = PR_FALSE;
if (IsDefunct())
return NS_ERROR_FAILURE;
*aValid = IsValid();
return NS_OK;
}
@ -2616,33 +2610,14 @@ NS_IMETHODIMP
nsAccessible::GetSelected(PRBool *aSelected)
{
NS_ENSURE_ARG_POINTER(aSelected);
*aSelected = PR_FALSE;
*aSelected = (gLastFocusedNode == GetNode());
if (IsDefunct())
return NS_ERROR_FAILURE;
*aSelected = IsSelected();
return NS_OK;
}
nsresult
nsAccessible::GetLinkOffset(PRInt32 *aStartOffset, PRInt32 *aEndOffset)
{
nsAccessible *parent = GetParent();
NS_ENSURE_STATE(parent);
PRUint32 characterCount = 0;
PRInt32 childCount = parent->GetChildCount();
for (PRInt32 childIdx = 0; childIdx < childCount; childIdx++) {
nsAccessible *sibling = parent->GetChildAt(childIdx);
if (sibling == this) {
*aStartOffset = characterCount;
*aEndOffset = characterCount + 1;
return NS_OK;
}
characterCount += nsAccUtils::TextLength(sibling);
}
return NS_ERROR_FAILURE;
}
nsresult
@ -2969,6 +2944,95 @@ nsAccessible::IsInCache()
#endif
////////////////////////////////////////////////////////////////////////////////
// HyperLinkAccessible methods
bool
nsAccessible::IsHyperLink()
{
// Every embedded accessible within hypertext accessible implements
// hyperlink interface.
nsRefPtr<nsHyperTextAccessible> hyperText = do_QueryObject(GetParent());
return hyperText && nsAccUtils::IsEmbeddedObject(this);
}
PRUint32
nsAccessible::StartOffset()
{
NS_PRECONDITION(IsHyperLink(), "StartOffset is called not on hyper link!");
nsRefPtr<nsHyperTextAccessible> hyperText(do_QueryObject(GetParent()));
return hyperText ? hyperText->GetChildOffset(this) : 0;
}
PRUint32
nsAccessible::EndOffset()
{
NS_PRECONDITION(IsHyperLink(), "EndOffset is called on not hyper link!");
nsRefPtr<nsHyperTextAccessible> hyperText(do_QueryObject(GetParent()));
return hyperText ? (hyperText->GetChildOffset(this) + 1) : 0;
}
bool
nsAccessible::IsValid()
{
NS_PRECONDITION(IsHyperLink(), "IsValid is called on not hyper link!");
PRUint32 state = nsAccUtils::State(this);
return (0 == (state & nsIAccessibleStates::STATE_INVALID));
// XXX In order to implement this we would need to follow every link
// Perhaps we can get information about invalid links from the cache
// In the mean time authors can use role="link" aria-invalid="true"
// to force it for links they internally know to be invalid
}
bool
nsAccessible::IsSelected()
{
NS_PRECONDITION(IsHyperLink(), "IsSelected is called on not hyper link!");
return (gLastFocusedNode == GetNode());
}
PRUint32
nsAccessible::AnchorCount()
{
NS_PRECONDITION(IsHyperLink(), "AnchorCount is called on not hyper link!");
return 1;
}
nsAccessible*
nsAccessible::GetAnchor(PRUint32 aAnchorIndex)
{
NS_PRECONDITION(IsHyperLink(), "GetAnchor is called on not hyper link!");
return aAnchorIndex == 0 ? this : nsnull;
}
already_AddRefed<nsIURI>
nsAccessible::GetAnchorURI(PRUint32 aAnchorIndex)
{
NS_PRECONDITION(IsHyperLink(), "GetAnchorURI is called on not hyper link!");
if (aAnchorIndex != 0)
return nsnull;
// Check if it's a simple xlink.
if (nsCoreUtils::IsXLink(mContent)) {
nsAutoString href;
mContent->GetAttr(kNameSpaceID_XLink, nsAccessibilityAtoms::href, href);
nsCOMPtr<nsIURI> baseURI = mContent->GetBaseURI();
nsCOMPtr<nsIDocument> document = mContent->GetOwnerDoc();
nsIURI* anchorURI = nsnull;
NS_NewURI(&anchorURI, href,
document ? document->GetDocumentCharacterSet().get() : nsnull,
baseURI);
return anchorURI;
}
return nsnull;
}
////////////////////////////////////////////////////////////////////////////////
// nsAccessible protected methods

View File

@ -327,6 +327,49 @@ public:
*/
void TestChildCache(nsAccessible *aCachedChild);
//////////////////////////////////////////////////////////////////////////////
// HyperLinkAccessible
/**
* Return true if the accessible is hyper link accessible.
*/
virtual bool IsHyperLink();
/**
* Return the start offset of the link within the parent accessible.
*/
virtual PRUint32 StartOffset();
/**
* Return the end offset of the link within the parent accessible.
*/
virtual PRUint32 EndOffset();
/**
* Return true if the link is valid (e. g. points to a valid URL).
*/
virtual bool IsValid();
/**
* Return true if the link currently has the focus.
*/
virtual bool IsSelected();
/**
* Return the number of anchors within the link.
*/
virtual PRUint32 AnchorCount();
/**
* Returns an anchor accessible at the given index.
*/
virtual nsAccessible* GetAnchor(PRUint32 aAnchorIndex);
/**
* Returns an anchor URI at the given index.
*/
virtual already_AddRefed<nsIURI> GetAnchorURI(PRUint32 aAnchorIndex);
protected:
//////////////////////////////////////////////////////////////////////////////
@ -383,9 +426,6 @@ protected:
*/
nsAccessible *GetFirstAvailableAccessible(nsINode *aStartNode) const;
// Hyperlink helpers
virtual nsresult GetLinkOffset(PRInt32* aStartOffset, PRInt32* aEndOffset);
//////////////////////////////////////////////////////////////////////////////
// Action helpers

View File

@ -204,27 +204,6 @@ nsLinkableAccessible::GetKeyboardShortcut(nsAString& aKeyboardShortcut)
return nsAccessible::GetKeyboardShortcut(aKeyboardShortcut);
}
////////////////////////////////////////////////////////////////////////////////
// nsLinkableAccessible. nsIAccessibleHyperLink
NS_IMETHODIMP
nsLinkableAccessible::GetURI(PRInt32 aIndex, nsIURI **aURI)
{
if (mIsLink) {
nsAccessible *actionAcc = GetActionAccessible();
if (actionAcc) {
nsCOMPtr<nsIAccessibleHyperLink> hyperLinkAcc = do_QueryObject(actionAcc);
NS_ASSERTION(hyperLinkAcc,
"nsIAccessibleHyperLink isn't implemented.");
if (hyperLinkAcc)
return hyperLinkAcc->GetURI(aIndex, aURI);
}
}
return NS_ERROR_INVALID_ARG;
}
////////////////////////////////////////////////////////////////////////////////
// nsLinkableAccessible. nsAccessNode
@ -242,6 +221,26 @@ nsLinkableAccessible::Shutdown()
nsAccessibleWrap::Shutdown();
}
////////////////////////////////////////////////////////////////////////////////
// nsLinkableAccessible: HyperLinkAccessible
already_AddRefed<nsIURI>
nsLinkableAccessible::GetAnchorURI(PRUint32 aAnchorIndex)
{
if (mIsLink) {
nsAccessible* link = GetActionAccessible();
if (link) {
NS_ASSERTION(link->IsHyperLink(),
"nsIAccessibleHyperLink isn't implemented.");
if (link->IsHyperLink())
return link->GetAnchorURI(aAnchorIndex);
}
}
return nsnull;
}
////////////////////////////////////////////////////////////////////////////////
// nsLinkableAccessible

View File

@ -96,9 +96,6 @@ public:
NS_IMETHOD TakeFocus();
NS_IMETHOD GetKeyboardShortcut(nsAString& _retval);
// nsIAccessibleHyperLink
NS_IMETHOD GetURI(PRInt32 i, nsIURI **aURI);
// nsAccessNode
virtual PRBool Init();
virtual void Shutdown();
@ -106,6 +103,9 @@ public:
// nsAccessible
virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
// HyperLinkAccessible
virtual already_AddRefed<nsIURI> GetAnchorURI(PRUint32 aAnchorIndex);
protected:
/**
* Return an accessible for cached action node.

View File

@ -65,51 +65,6 @@ nsHTMLImageMapAccessible::
NS_IMPL_ISUPPORTS_INHERITED0(nsHTMLImageMapAccessible, nsHTMLImageAccessible)
////////////////////////////////////////////////////////////////////////////////
// nsHTMLImageMapAccessible: nsIAccessibleHyperLink
NS_IMETHODIMP
nsHTMLImageMapAccessible::GetAnchorCount(PRInt32 *aAnchorCount)
{
NS_ENSURE_ARG_POINTER(aAnchorCount);
return GetChildCount(aAnchorCount);
}
NS_IMETHODIMP
nsHTMLImageMapAccessible::GetURI(PRInt32 aIndex, nsIURI **aURI)
{
NS_ENSURE_ARG_POINTER(aURI);
*aURI = nsnull;
nsAccessible *areaAcc = GetChildAt(aIndex);
if (!areaAcc)
return NS_ERROR_INVALID_ARG;
nsCOMPtr<nsIDOMNode> areaNode;
areaAcc->GetDOMNode(getter_AddRefs(areaNode));
nsCOMPtr<nsIContent> link(do_QueryInterface(areaNode));
if (link)
*aURI = link->GetHrefURI().get();
return NS_OK;
}
NS_IMETHODIMP
nsHTMLImageMapAccessible::GetAnchor(PRInt32 aIndex, nsIAccessible **aAccessible)
{
NS_ENSURE_ARG_POINTER(aAccessible);
*aAccessible = nsnull;
nsAccessible *areaAcc = GetChildAt(aIndex);
if (!areaAcc)
return NS_ERROR_INVALID_ARG;
NS_ADDREF(*aAccessible = areaAcc);
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// nsHTMLImageMapAccessible: nsAccessible public
@ -120,6 +75,32 @@ nsHTMLImageMapAccessible::GetRoleInternal(PRUint32 *aRole)
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// nsHTMLImageMapAccessible: HyperLinkAccessible
PRUint32
nsHTMLImageMapAccessible::AnchorCount()
{
return GetChildCount();
}
nsAccessible*
nsHTMLImageMapAccessible::GetAnchor(PRUint32 aAnchorIndex)
{
return GetChildAt(aAnchorIndex);
}
already_AddRefed<nsIURI>
nsHTMLImageMapAccessible::GetAnchorURI(PRUint32 aAnchorIndex)
{
nsAccessible* area = GetChildAt(aAnchorIndex);
if (!area)
return nsnull;
nsIContent* linkContent = area->GetContent();
return linkContent ? linkContent->GetHrefURI() : nsnull;
}
////////////////////////////////////////////////////////////////////////////////
// nsHTMLImageMapAccessible: nsAccessible protected
@ -281,6 +262,26 @@ nsHTMLAreaAccessible::GetChildAtPoint(PRInt32 aX, PRInt32 aY,
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// nsHTMLImageMapAccessible: HyperLinkAccessible
PRUint32
nsHTMLAreaAccessible::StartOffset()
{
// Image map accessible is not hypertext accessible therefore
// StartOffset/EndOffset implementations of nsAccessible doesn't work here.
// We return index in parent because image map contains area links only which
// are embedded objects.
// XXX: image map should be a hypertext accessible.
return GetIndexInParent();
}
PRUint32
nsHTMLAreaAccessible::EndOffset()
{
return GetIndexInParent() + 1;
}
////////////////////////////////////////////////////////////////////////////////
// nsHTMLAreaAccessible: nsAccessible protected

View File

@ -57,14 +57,14 @@ public:
// nsISupports and cycle collector
NS_DECL_ISUPPORTS_INHERITED
// nsIAccessibleHyperLink
NS_IMETHOD GetAnchorCount(PRInt32 *aAnchorCount);
NS_IMETHOD GetURI(PRInt32 aIndex, nsIURI **aURI);
NS_IMETHOD GetAnchor(PRInt32 aIndex, nsIAccessible **aAccessible);
// nsAccessible
virtual nsresult GetRoleInternal(PRUint32 *aRole);
// HyperLinkAccessible
virtual PRUint32 AnchorCount();
virtual nsAccessible* GetAnchor(PRUint32 aAnchorIndex);
virtual already_AddRefed<nsIURI> GetAnchorURI(PRUint32 aAnchorIndex);
protected:
// nsAccessible
@ -98,6 +98,10 @@ public:
PRBool aDeepestChild,
nsIAccessible **aChild);
// HyperLinkAccessible
virtual PRUint32 StartOffset();
virtual PRUint32 EndOffset();
protected:
// nsAccessible

View File

@ -163,23 +163,19 @@ nsHTMLLinkAccessible::DoAction(PRUint8 aIndex)
}
////////////////////////////////////////////////////////////////////////////////
// nsIAccessibleHyperLink
// HyperLinkAccessible
NS_IMETHODIMP
nsHTMLLinkAccessible::GetURI(PRInt32 aIndex, nsIURI **aURI)
bool
nsHTMLLinkAccessible::IsHyperLink()
{
NS_ENSURE_ARG_POINTER(aURI);
*aURI = nsnull;
// Expose HyperLinkAccessible unconditionally.
return true;
}
if (aIndex != 0)
return NS_ERROR_INVALID_ARG;
if (IsDefunct())
return NS_ERROR_FAILURE;
nsCOMPtr<nsIURI> uri = mContent->GetHrefURI();
uri.forget(aURI);
return NS_OK;
already_AddRefed<nsIURI>
nsHTMLLinkAccessible::GetAnchorURI(PRUint32 aAnchorIndex)
{
return aAnchorIndex == 0 ? mContent->GetHrefURI() : nsnull;
}
////////////////////////////////////////////////////////////////////////////////

View File

@ -56,13 +56,14 @@ public:
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
NS_IMETHOD DoAction(PRUint8 aIndex);
// nsIAccessibleHyperLink
NS_IMETHOD GetURI(PRInt32 aIndex, nsIURI **aURI);
// nsAccessible
virtual nsresult GetRoleInternal(PRUint32 *aRole);
virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
// HyperLinkAccessible
virtual bool IsHyperLink();
virtual already_AddRefed<nsIURI> GetAnchorURI(PRUint32 aAnchorIndex);
protected:
enum { eAction_Jump = 0 };

View File

@ -44,15 +44,8 @@
#include "AccessibleHyperlink.h"
#include "AccessibleHyperlink_i.c"
#include "nsIAccessible.h"
#include "nsIAccessibleHyperlink.h"
#include "nsAccessible.h"
#include "nsIWinAccessNode.h"
#include "nsAccessNodeWrap.h"
#include "nsCOMPtr.h"
#include "nsString.h"
#include "nsIURI.h"
// IUnknown
@ -62,8 +55,8 @@ CAccessibleHyperlink::QueryInterface(REFIID iid, void** ppv)
*ppv = NULL;
if (IID_IAccessibleHyperlink == iid) {
nsCOMPtr<nsIAccessibleHyperLink> acc(do_QueryObject(this));
if (!acc)
nsRefPtr<nsAccessible> thisObj = do_QueryObject(this);
if (!thisObj->IsHyperLink())
return E_NOINTERFACE;
*ppv = static_cast<IAccessibleHyperlink*>(this);
@ -82,21 +75,23 @@ CAccessibleHyperlink::get_anchor(long aIndex, VARIANT *aAnchor)
__try {
VariantInit(aAnchor);
nsCOMPtr<nsIAccessibleHyperLink> acc(do_QueryObject(this));
if (!acc)
nsRefPtr<nsAccessible> thisObj = do_QueryObject(this);
if (thisObj->IsDefunct() || !thisObj->IsHyperLink())
return E_FAIL;
nsCOMPtr<nsIAccessible> anchor;
nsresult rv = acc->GetAnchor(aIndex, getter_AddRefs(anchor));
if (NS_FAILED(rv))
return GetHRESULT(rv);
if (aIndex < 0 || aIndex >= static_cast<long>(thisObj->AnchorCount()))
return E_INVALIDARG;
nsCOMPtr<nsIWinAccessNode> winAccessNode(do_QueryInterface(anchor));
nsAccessible* anchor = thisObj->GetAnchor(aIndex);
if (!anchor)
return S_FALSE;
nsCOMPtr<nsIWinAccessNode> winAccessNode(do_QueryObject(anchor));
if (!winAccessNode)
return E_FAIL;
void *instancePtr = NULL;
rv = winAccessNode->QueryNativeInterface(IID_IUnknown, &instancePtr);
nsresult rv = winAccessNode->QueryNativeInterface(IID_IUnknown, &instancePtr);
if (NS_FAILED(rv))
return E_FAIL;
@ -115,17 +110,19 @@ CAccessibleHyperlink::get_anchorTarget(long aIndex, VARIANT *aAnchorTarget)
__try {
VariantInit(aAnchorTarget);
nsCOMPtr<nsIAccessibleHyperLink> acc(do_QueryObject(this));
if (!acc)
nsRefPtr<nsAccessible> thisObj = do_QueryObject(this);
if (thisObj->IsDefunct() || !thisObj->IsHyperLink())
return E_FAIL;
nsCOMPtr<nsIURI> uri;
nsresult rv = acc->GetURI(aIndex, getter_AddRefs(uri));
if (NS_FAILED(rv) || !uri)
return GetHRESULT(rv);
if (aIndex < 0 || aIndex >= static_cast<long>(thisObj->AnchorCount()))
return E_INVALIDARG;
nsCOMPtr<nsIURI> uri = thisObj->GetAnchorURI(aIndex);
if (!uri)
return S_FALSE;
nsCAutoString prePath;
rv = uri->GetPrePath(prePath);
nsresult rv = uri->GetPrePath(prePath);
if (NS_FAILED(rv))
return GetHRESULT(rv);
@ -153,16 +150,11 @@ CAccessibleHyperlink::get_startIndex(long *aIndex)
__try {
*aIndex = 0;
nsCOMPtr<nsIAccessibleHyperLink> acc(do_QueryObject(this));
if (!acc)
nsRefPtr<nsAccessible> thisObj = do_QueryObject(this);
if (thisObj->IsDefunct() || !thisObj->IsHyperLink())
return E_FAIL;
PRInt32 index = 0;
nsresult rv = acc->GetStartIndex(&index);
if (NS_FAILED(rv))
return GetHRESULT(rv);
*aIndex = index;
*aIndex = thisObj->StartOffset();
return S_OK;
} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
@ -175,16 +167,11 @@ CAccessibleHyperlink::get_endIndex(long *aIndex)
__try {
*aIndex = 0;
nsCOMPtr<nsIAccessibleHyperLink> acc(do_QueryObject(this));
if (!acc)
nsRefPtr<nsAccessible> thisObj = do_QueryObject(this);
if (thisObj->IsDefunct() || !thisObj->IsHyperLink())
return E_FAIL;
PRInt32 index = 0;
nsresult rv = acc->GetEndIndex(&index);
if (NS_FAILED(rv))
return GetHRESULT(rv);
*aIndex = index;
*aIndex = thisObj->EndOffset();
return S_OK;
} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
@ -197,16 +184,11 @@ CAccessibleHyperlink::get_valid(boolean *aValid)
__try {
*aValid = false;
nsCOMPtr<nsIAccessibleHyperLink> acc(do_QueryObject(this));
if (!acc)
nsRefPtr<nsAccessible> thisObj = do_QueryObject(this);
if (thisObj->IsDefunct() || !thisObj->IsHyperLink())
return E_FAIL;
PRBool isValid = PR_FALSE;
nsresult rv = acc->GetValid(&isValid);
if (NS_FAILED(rv))
return GetHRESULT(rv);
*aValid = isValid;
*aValid = thisObj->IsValid();
return S_OK;
} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }

View File

@ -238,26 +238,52 @@ nsXULLinkAccessible::DoAction(PRUint8 aIndex)
}
////////////////////////////////////////////////////////////////////////////////
// nsXULLinkAccessible. nsIAccessibleHyperLink
// nsXULLinkAccessible: HyperLinkAccessible
NS_IMETHODIMP
nsXULLinkAccessible::GetURI(PRInt32 aIndex, nsIURI **aURI)
bool
nsXULLinkAccessible::IsHyperLink()
{
NS_ENSURE_ARG_POINTER(aURI);
*aURI = nsnull;
// Expose HyperLinkAccessible unconditionally.
return true;
}
if (aIndex != 0)
return NS_ERROR_INVALID_ARG;
PRUint32
nsXULLinkAccessible::StartOffset()
{
// If XUL link accessible is not contained by hypertext accessible then
// start offset matches index in parent because the parent doesn't contains
// a text.
// XXX: accessible parent of XUL link accessible should be a hypertext
// accessible.
if (nsAccessible::IsHyperLink())
return nsAccessible::StartOffset();
return GetIndexInParent();
}
if (IsDefunct())
return NS_ERROR_FAILURE;
PRUint32
nsXULLinkAccessible::EndOffset()
{
if (nsAccessible::IsHyperLink())
return nsAccessible::EndOffset();
return GetIndexInParent() + 1;
}
already_AddRefed<nsIURI>
nsXULLinkAccessible::GetAnchorURI(PRUint32 aAnchorIndex)
{
if (aAnchorIndex != 0)
return nsnull;
nsAutoString href;
mContent->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::href, href);
nsCOMPtr<nsIURI> baseURI = mContent->GetBaseURI();
nsIDocument* document = mContent->GetOwnerDoc();
return NS_NewURI(aURI, href,
document ? document->GetDocumentCharacterSet().get() : nsnull,
baseURI);
nsIURI* anchorURI = nsnull;
NS_NewURI(&anchorURI, href,
document ? document->GetDocumentCharacterSet().get() : nsnull,
baseURI);
return anchorURI;
}

View File

@ -91,14 +91,17 @@ public:
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
NS_IMETHOD DoAction(PRUint8 aIndex);
// nsIAccessibleHyperLink
NS_IMETHOD GetURI(PRInt32 aIndex, nsIURI **aURI);
// nsAccessible
virtual nsresult GetNameInternal(nsAString& aName);
virtual nsresult GetRoleInternal(PRUint32 *aRole);
virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
// HyperLinkAccessible
virtual bool IsHyperLink();
virtual PRUint32 StartOffset();
virtual PRUint32 EndOffset();
virtual already_AddRefed<nsIURI> GetAnchorURI(PRUint32 aAnchorIndex);
protected:
enum { eAction_Jump = 0 };

View File

@ -42,7 +42,17 @@ srcdir = @srcdir@
VPATH = @srcdir@
relativesrcdir = accessible
DIRS = actions attributes events relations selectable states table tree
DIRS = \
actions \
attributes \
events \
hyperlink \
relations \
selectable \
states \
table \
tree \
$(null)
include $(DEPTH)/config/autoconf.mk
include $(topsrcdir)/config/rules.mk
@ -98,8 +108,6 @@ _TEST_FILES =\
test_nsIAccessible_selects.html \
test_nsIAccessible_focus.html \
test_nsIAccessibleDocument.html \
test_nsIAccessibleHyperLink.html \
test_nsIAccessibleHyperLink.xul \
test_nsIAccessibleHyperText.html \
test_nsIAccessibleImage.html \
test_nsIAccessNode_utils.html \

View File

@ -0,0 +1,54 @@
#
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is
# Mozilla Foundation.
# Portions created by the Initial Developer are Copyright (C) 2010
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Alexander Surkov <surkov.alexander@gmail.com> (original author)
#
# 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"),
# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
DEPTH = ../../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
relativesrcdir = accessible/hyperlink
include $(DEPTH)/config/autoconf.mk
include $(topsrcdir)/config/rules.mk
_TEST_FILES =\
test_general.html \
test_general.xul \
$(NULL)
libs:: $(_TEST_FILES)
$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/a11y/$(relativesrcdir)