2001-10-09 21:52:36 +00:00
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* ***** BEGIN LICENSE BLOCK *****
|
2004-04-17 21:52:36 +00:00
|
|
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
2001-10-09 21:52:36 +00:00
|
|
|
*
|
2004-04-17 21:52:36 +00:00
|
|
|
* 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/
|
2001-10-09 21:52:36 +00:00
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*
|
2004-04-17 21:52:36 +00:00
|
|
|
* The Initial Developer of the Original Code is
|
2001-10-09 21:52:36 +00:00
|
|
|
* Netscape Communications Corporation.
|
|
|
|
* Portions created by the Initial Developer are Copyright (C) 1998
|
|
|
|
* the Initial Developer. All Rights Reserved.
|
|
|
|
*
|
|
|
|
* Contributor(s):
|
2004-04-17 21:52:36 +00:00
|
|
|
* John Gaunt (jgaunt@netscape.com)
|
2001-10-09 21:52:36 +00:00
|
|
|
*
|
|
|
|
* Alternatively, the contents of this file may be used under the terms of
|
2004-04-17 21:52:36 +00:00
|
|
|
* 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"),
|
2001-10-09 21:52:36 +00:00
|
|
|
* 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
|
2004-04-17 21:52:36 +00:00
|
|
|
* use your version of this file under the terms of the MPL, indicate your
|
2001-10-09 21:52:36 +00:00
|
|
|
* 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
|
2004-04-17 21:52:36 +00:00
|
|
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
2001-10-09 21:52:36 +00:00
|
|
|
*
|
|
|
|
* ***** END LICENSE BLOCK ***** */
|
|
|
|
|
|
|
|
#include "nsBaseWidgetAccessible.h"
|
2005-01-21 03:50:26 +00:00
|
|
|
#include "nsAccessibilityAtoms.h"
|
2003-05-15 08:37:38 +00:00
|
|
|
#include "nsIAccessibilityService.h"
|
2003-06-19 18:12:52 +00:00
|
|
|
#include "nsIAccessibleDocument.h"
|
2003-04-15 08:45:55 +00:00
|
|
|
#include "nsAccessibleWrap.h"
|
2001-10-09 21:52:36 +00:00
|
|
|
#include "nsGUIEvent.h"
|
2006-06-21 13:29:10 +00:00
|
|
|
#include "nsHyperTextAccessible.h"
|
2001-10-09 21:52:36 +00:00
|
|
|
#include "nsILink.h"
|
2005-10-04 02:33:58 +00:00
|
|
|
#include "nsIFrame.h"
|
2005-01-21 03:50:26 +00:00
|
|
|
#include "nsINameSpaceManager.h"
|
2004-07-31 23:15:21 +00:00
|
|
|
#include "nsPresContext.h"
|
2001-10-09 21:52:36 +00:00
|
|
|
#include "nsIPresShell.h"
|
2002-10-25 00:08:44 +00:00
|
|
|
#include "nsIServiceManager.h"
|
2005-01-30 01:31:50 +00:00
|
|
|
#include "nsIURI.h"
|
2001-10-09 21:52:36 +00:00
|
|
|
|
|
|
|
//-------------
|
2003-06-02 08:32:46 +00:00
|
|
|
// nsLeafAccessible
|
2001-10-09 21:52:36 +00:00
|
|
|
//-------------
|
|
|
|
|
|
|
|
nsLeafAccessible::nsLeafAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell):
|
2003-04-01 20:02:51 +00:00
|
|
|
nsAccessibleWrap(aNode, aShell)
|
2001-10-09 21:52:36 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2003-04-01 20:02:51 +00:00
|
|
|
NS_IMPL_ISUPPORTS_INHERITED0(nsLeafAccessible, nsAccessible)
|
|
|
|
|
2003-07-31 08:09:39 +00:00
|
|
|
/* nsIAccessible getFirstChild (); */
|
|
|
|
NS_IMETHODIMP nsLeafAccessible::GetFirstChild(nsIAccessible **_retval)
|
2001-10-09 21:52:36 +00:00
|
|
|
{
|
|
|
|
*_retval = nsnull;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2003-07-31 08:09:39 +00:00
|
|
|
/* nsIAccessible getLastChild (); */
|
|
|
|
NS_IMETHODIMP nsLeafAccessible::GetLastChild(nsIAccessible **_retval)
|
2001-10-09 21:52:36 +00:00
|
|
|
{
|
|
|
|
*_retval = nsnull;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* long getAccChildCount (); */
|
2003-07-31 08:09:39 +00:00
|
|
|
NS_IMETHODIMP nsLeafAccessible::GetChildCount(PRInt32 *_retval)
|
2001-10-09 21:52:36 +00:00
|
|
|
{
|
|
|
|
*_retval = 0;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2006-10-30 03:05:43 +00:00
|
|
|
/* readonly attribute boolean allowsAnonChildAccessibles; */
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsLeafAccessible::GetAllowsAnonChildAccessibles(PRBool *aAllowsAnonChildren)
|
|
|
|
{
|
|
|
|
*aAllowsAnonChildren = PR_FALSE;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2001-10-09 21:52:36 +00:00
|
|
|
|
|
|
|
//----------------
|
|
|
|
// nsLinkableAccessible
|
|
|
|
//----------------
|
|
|
|
|
2003-05-20 02:02:56 +00:00
|
|
|
nsLinkableAccessible::nsLinkableAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell) :
|
2006-06-21 13:29:10 +00:00
|
|
|
nsHyperTextAccessible(aNode, aShell),
|
2005-08-10 01:51:39 +00:00
|
|
|
mActionContent(nsnull),
|
|
|
|
mIsLink(PR_FALSE),
|
|
|
|
mIsOnclick(PR_FALSE)
|
|
|
|
{
|
2001-10-09 21:52:36 +00:00
|
|
|
}
|
|
|
|
|
2006-06-21 13:29:10 +00:00
|
|
|
NS_IMPL_ISUPPORTS_INHERITED0(nsLinkableAccessible, nsHyperTextAccessible)
|
2003-04-01 20:02:51 +00:00
|
|
|
|
2003-07-31 08:09:39 +00:00
|
|
|
NS_IMETHODIMP nsLinkableAccessible::TakeFocus()
|
2002-07-03 16:38:15 +00:00
|
|
|
{
|
2005-08-10 01:51:39 +00:00
|
|
|
if (mActionContent && mActionContent->IsFocusable()) {
|
|
|
|
mActionContent->SetFocus(nsCOMPtr<nsPresContext>(GetPresContext()));
|
2002-07-03 16:38:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2003-07-31 08:09:39 +00:00
|
|
|
/* long GetState (); */
|
|
|
|
NS_IMETHODIMP nsLinkableAccessible::GetState(PRUint32 *aState)
|
2001-10-09 21:52:36 +00:00
|
|
|
{
|
2006-06-21 13:29:10 +00:00
|
|
|
nsHyperTextAccessible::GetState(aState);
|
2005-08-10 01:51:39 +00:00
|
|
|
if (mIsLink) {
|
2003-05-15 08:37:38 +00:00
|
|
|
*aState |= STATE_LINKED;
|
2005-10-17 13:42:33 +00:00
|
|
|
nsCOMPtr<nsILink> link = do_QueryInterface(mActionContent);
|
|
|
|
if (link) {
|
|
|
|
nsLinkState linkState;
|
|
|
|
link->GetLinkState(linkState);
|
|
|
|
if (linkState == eLinkState_Visited) {
|
|
|
|
*aState |= STATE_TRAVERSED;
|
|
|
|
}
|
|
|
|
}
|
2001-12-17 23:52:24 +00:00
|
|
|
// Make sure we also include all the states of the parent link, such as focusable, focused, etc.
|
|
|
|
PRUint32 role;
|
2003-07-31 08:09:39 +00:00
|
|
|
GetRole(&role);
|
2001-12-17 23:52:24 +00:00
|
|
|
if (role != ROLE_LINK) {
|
2006-10-23 09:45:34 +00:00
|
|
|
nsCOMPtr<nsIAccessible> parentAccessible(GetParent());
|
2001-12-17 23:52:24 +00:00
|
|
|
if (parentAccessible) {
|
|
|
|
PRUint32 orState = 0;
|
2005-01-28 02:35:26 +00:00
|
|
|
parentAccessible->GetFinalState(&orState);
|
2003-05-15 08:37:38 +00:00
|
|
|
*aState |= orState;
|
2001-12-17 23:52:24 +00:00
|
|
|
}
|
|
|
|
}
|
2005-08-10 01:51:39 +00:00
|
|
|
}
|
|
|
|
if (mActionContent && !mActionContent->IsFocusable()) {
|
|
|
|
*aState &= ~STATE_FOCUSABLE; // Links must have href or tabindex
|
2001-12-17 23:52:24 +00:00
|
|
|
}
|
2002-01-09 10:02:29 +00:00
|
|
|
|
2006-06-21 13:29:10 +00:00
|
|
|
// XXX What if we're in a contenteditable container?
|
|
|
|
// We may need to go up the parent chain unless a better API is found
|
|
|
|
nsCOMPtr<nsIAccessible> docAccessible =
|
|
|
|
do_QueryInterface(nsCOMPtr<nsIAccessibleDocument>(GetDocAccessible()));
|
2005-01-30 01:31:50 +00:00
|
|
|
if (docAccessible) {
|
|
|
|
PRBool isEditable;
|
|
|
|
docAccessible->GetIsEditable(&isEditable);
|
|
|
|
if (isEditable) {
|
|
|
|
*aState &= ~(STATE_FOCUSED | STATE_FOCUSABLE); // Links not focusable in editor
|
2003-05-15 08:37:38 +00:00
|
|
|
}
|
|
|
|
}
|
2001-10-09 21:52:36 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-07-31 08:09:39 +00:00
|
|
|
NS_IMETHODIMP nsLinkableAccessible::GetValue(nsAString& _retval)
|
2001-10-09 21:52:36 +00:00
|
|
|
{
|
2005-08-10 01:51:39 +00:00
|
|
|
if (mIsLink) {
|
|
|
|
nsCOMPtr<nsIDOMNode> linkNode(do_QueryInterface(mActionContent));
|
2003-04-15 08:45:55 +00:00
|
|
|
nsCOMPtr<nsIPresShell> presShell(do_QueryReferent(mWeakShell));
|
2002-08-01 21:36:02 +00:00
|
|
|
if (linkNode && presShell)
|
|
|
|
return presShell->GetLinkLocation(linkNode, _retval);
|
2001-10-09 21:52:36 +00:00
|
|
|
}
|
2002-03-01 07:27:29 +00:00
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
2001-10-09 21:52:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* PRUint8 getAccNumActions (); */
|
2005-08-10 01:51:39 +00:00
|
|
|
NS_IMETHODIMP nsLinkableAccessible::GetNumActions(PRUint8 *aNumActions)
|
2001-10-09 21:52:36 +00:00
|
|
|
{
|
2005-08-10 01:51:39 +00:00
|
|
|
*aNumActions = mActionContent ? 1 : 0;
|
2001-10-09 21:52:36 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* wstring getAccActionName (in PRUint8 index); */
|
2005-08-10 01:51:39 +00:00
|
|
|
NS_IMETHODIMP nsLinkableAccessible::GetActionName(PRUint8 index, nsAString& aActionName)
|
2001-10-09 21:52:36 +00:00
|
|
|
{
|
|
|
|
// Action 0 (default action): Jump to link
|
2005-08-10 01:51:39 +00:00
|
|
|
aActionName.Truncate();
|
2001-11-07 00:12:16 +00:00
|
|
|
if (index == eAction_Jump) {
|
2005-08-10 01:51:39 +00:00
|
|
|
if (mIsLink) {
|
|
|
|
return nsAccessible::GetTranslatedString(NS_LITERAL_STRING("jump"), aActionName);
|
|
|
|
}
|
|
|
|
else if (mIsOnclick) {
|
|
|
|
return nsAccessible::GetTranslatedString(NS_LITERAL_STRING("click"), aActionName);
|
2001-10-09 21:52:36 +00:00
|
|
|
}
|
2002-03-01 07:27:29 +00:00
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
2001-10-09 21:52:36 +00:00
|
|
|
}
|
2002-03-01 07:27:29 +00:00
|
|
|
return NS_ERROR_INVALID_ARG;
|
2001-10-09 21:52:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* void accDoAction (in PRUint8 index); */
|
2003-07-31 08:09:39 +00:00
|
|
|
NS_IMETHODIMP nsLinkableAccessible::DoAction(PRUint8 index)
|
2001-10-09 21:52:36 +00:00
|
|
|
{
|
|
|
|
// Action 0 (default action): Jump to link
|
2002-07-03 16:38:15 +00:00
|
|
|
if (index == eAction_Jump) {
|
2005-08-10 01:51:39 +00:00
|
|
|
if (mActionContent) {
|
2005-08-19 19:27:43 +00:00
|
|
|
return DoCommand(mActionContent);
|
2001-10-09 21:52:36 +00:00
|
|
|
}
|
|
|
|
}
|
2002-03-01 07:27:29 +00:00
|
|
|
return NS_ERROR_INVALID_ARG;
|
2001-10-09 21:52:36 +00:00
|
|
|
}
|
|
|
|
|
2005-08-10 01:51:39 +00:00
|
|
|
NS_IMETHODIMP nsLinkableAccessible::GetKeyboardShortcut(nsAString& aKeyboardShortcut)
|
2002-10-25 00:08:44 +00:00
|
|
|
{
|
2005-08-10 01:51:39 +00:00
|
|
|
if (mActionContent) {
|
|
|
|
nsCOMPtr<nsIDOMNode> actionNode(do_QueryInterface(mActionContent));
|
|
|
|
if (actionNode && mDOMNode != actionNode) {
|
|
|
|
nsCOMPtr<nsIAccessible> accessible;
|
2002-10-25 00:08:44 +00:00
|
|
|
nsCOMPtr<nsIAccessibilityService> accService =
|
|
|
|
do_GetService("@mozilla.org/accessibilityService;1");
|
2005-08-10 01:51:39 +00:00
|
|
|
accService->GetAccessibleInWeakShell(actionNode, mWeakShell,
|
|
|
|
getter_AddRefs(accessible));
|
|
|
|
if (accessible) {
|
|
|
|
accessible->GetKeyboardShortcut(aKeyboardShortcut);
|
|
|
|
}
|
|
|
|
return NS_OK;
|
2002-10-25 00:08:44 +00:00
|
|
|
}
|
|
|
|
}
|
2005-08-10 01:51:39 +00:00
|
|
|
return nsAccessible::GetKeyboardShortcut(aKeyboardShortcut);
|
2002-10-25 00:08:44 +00:00
|
|
|
}
|
2001-10-09 21:52:36 +00:00
|
|
|
|
2005-08-10 01:51:39 +00:00
|
|
|
void nsLinkableAccessible::CacheActionContent()
|
2001-10-09 21:52:36 +00:00
|
|
|
{
|
2003-07-28 21:35:53 +00:00
|
|
|
for (nsCOMPtr<nsIContent> walkUpContent(do_QueryInterface(mDOMNode));
|
|
|
|
walkUpContent;
|
|
|
|
walkUpContent = walkUpContent->GetParent()) {
|
2005-01-30 01:31:50 +00:00
|
|
|
nsIAtom *tag = walkUpContent->Tag();
|
2005-01-31 11:16:05 +00:00
|
|
|
if ((tag == nsAccessibilityAtoms::a || tag == nsAccessibilityAtoms::area)) {
|
2005-01-30 01:31:50 +00:00
|
|
|
// Currently we do not expose <link> tags, because they are not typically
|
|
|
|
// in <body> and rendered.
|
|
|
|
// We do not yet support xlinks
|
|
|
|
nsCOMPtr<nsILink> link = do_QueryInterface(walkUpContent);
|
|
|
|
NS_ASSERTION(link, "No nsILink for area or a");
|
|
|
|
nsCOMPtr<nsIURI> uri;
|
|
|
|
link->GetHrefURI(getter_AddRefs(uri));
|
|
|
|
if (uri) {
|
2005-08-10 01:51:39 +00:00
|
|
|
mActionContent = walkUpContent;
|
2005-08-10 22:01:42 +00:00
|
|
|
mIsLink = PR_TRUE;
|
2006-08-16 01:50:36 +00:00
|
|
|
break;
|
2005-01-30 01:31:50 +00:00
|
|
|
}
|
2001-10-09 21:52:36 +00:00
|
|
|
}
|
2005-08-10 01:51:39 +00:00
|
|
|
if (walkUpContent->HasAttr(kNameSpaceID_None,
|
|
|
|
nsAccessibilityAtoms::onclick)) {
|
|
|
|
mActionContent = walkUpContent;
|
|
|
|
mIsOnclick = PR_TRUE;
|
2006-08-16 01:50:36 +00:00
|
|
|
break;
|
2005-08-10 01:51:39 +00:00
|
|
|
}
|
2001-10-09 21:52:36 +00:00
|
|
|
}
|
|
|
|
}
|
2003-04-15 08:45:55 +00:00
|
|
|
|
2006-06-21 13:29:10 +00:00
|
|
|
// 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;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsILink> link(do_QueryInterface(mActionContent));
|
|
|
|
if (link) {
|
|
|
|
return link->GetHrefURI(aURI);
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
2006-02-01 18:53:54 +00:00
|
|
|
NS_IMETHODIMP nsLinkableAccessible::Init()
|
|
|
|
{
|
|
|
|
CacheActionContent();
|
2006-06-21 13:29:10 +00:00
|
|
|
return nsHyperTextAccessible::Init();
|
2006-02-01 18:53:54 +00:00
|
|
|
}
|
|
|
|
|
2003-04-15 08:45:55 +00:00
|
|
|
NS_IMETHODIMP nsLinkableAccessible::Shutdown()
|
|
|
|
{
|
2005-08-10 01:51:39 +00:00
|
|
|
mActionContent = nsnull;
|
2006-06-21 13:29:10 +00:00
|
|
|
return nsHyperTextAccessible::Shutdown();
|
2003-04-15 08:45:55 +00:00
|
|
|
}
|
2004-07-07 00:58:57 +00:00
|
|
|
|
2005-09-30 02:16:13 +00:00
|
|
|
//---------------------
|
|
|
|
// nsEnumRoleAccessible
|
|
|
|
//---------------------
|
|
|
|
|
|
|
|
nsEnumRoleAccessible::nsEnumRoleAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell, PRUint32 aRole) :
|
|
|
|
nsAccessibleWrap(aNode, aShell),
|
|
|
|
mRole(aRole)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMPL_ISUPPORTS_INHERITED0(nsEnumRoleAccessible, nsAccessible)
|