2007-03-22 10:30:00 -07:00
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* ***** 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
|
|
|
|
* Netscape Communications Corporation.
|
|
|
|
* Portions created by the Initial Developer are Copyright (C) 1998
|
|
|
|
* the Initial Developer. All Rights Reserved.
|
|
|
|
*
|
|
|
|
* Contributor(s):
|
|
|
|
* Author: Eric Vaughan (evaughan@netscape.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"),
|
|
|
|
* 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 ***** */
|
|
|
|
|
|
|
|
#include "nsHTMLFormControlAccessible.h"
|
2010-04-26 23:52:03 -07:00
|
|
|
|
|
|
|
#include "nsAccessibilityAtoms.h"
|
|
|
|
#include "nsAccUtils.h"
|
|
|
|
#include "nsRelUtils.h"
|
|
|
|
#include "nsTextEquivUtils.h"
|
|
|
|
|
2007-04-06 08:44:46 -07:00
|
|
|
#include "nsIDOMDocument.h"
|
2009-02-11 00:40:27 -08:00
|
|
|
#include "nsIDOMNSHTMLInputElement.h"
|
2007-03-22 10:30:00 -07:00
|
|
|
#include "nsIDOMHTMLInputElement.h"
|
2007-05-07 11:51:36 -07:00
|
|
|
#include "nsIDOMNSHTMLElement.h"
|
2007-03-22 10:30:00 -07:00
|
|
|
#include "nsIDOMNSEditableElement.h"
|
|
|
|
#include "nsIDOMNSHTMLButtonElement.h"
|
|
|
|
#include "nsIDOMHTMLFormElement.h"
|
|
|
|
#include "nsIDOMHTMLLegendElement.h"
|
|
|
|
#include "nsIDOMHTMLTextAreaElement.h"
|
2007-08-14 09:25:24 -07:00
|
|
|
#include "nsIEditor.h"
|
2007-03-22 10:30:00 -07:00
|
|
|
#include "nsIFrame.h"
|
|
|
|
#include "nsINameSpaceManager.h"
|
|
|
|
#include "nsISelectionController.h"
|
2007-07-24 23:24:00 -07:00
|
|
|
#include "jsapi.h"
|
|
|
|
#include "nsIJSContextStack.h"
|
|
|
|
#include "nsIServiceManager.h"
|
2007-03-22 10:30:00 -07:00
|
|
|
#include "nsITextControlFrame.h"
|
|
|
|
|
|
|
|
// --- checkbox -----
|
|
|
|
|
|
|
|
nsHTMLCheckboxAccessible::nsHTMLCheckboxAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell):
|
|
|
|
nsFormControlAccessible(aNode, aShell)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2009-03-07 07:38:58 -08:00
|
|
|
nsresult
|
|
|
|
nsHTMLCheckboxAccessible::GetRoleInternal(PRUint32 *aRole)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
2009-03-07 07:38:58 -08:00
|
|
|
*aRole = nsIAccessibleRole::ROLE_CHECKBUTTON;
|
2007-03-22 10:30:00 -07:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP nsHTMLCheckboxAccessible::GetNumActions(PRUint8 *_retval)
|
|
|
|
{
|
|
|
|
*_retval = 1;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP nsHTMLCheckboxAccessible::GetActionName(PRUint8 aIndex, nsAString& aName)
|
|
|
|
{
|
|
|
|
if (aIndex == eAction_Click) { // 0 is the magic value for default action
|
2009-03-09 08:10:40 -07:00
|
|
|
// cycle, check or uncheck
|
2007-03-22 10:30:00 -07:00
|
|
|
PRUint32 state;
|
2008-11-03 19:37:46 -08:00
|
|
|
nsresult rv = GetStateInternal(&state, nsnull);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
if (state & nsIAccessibleStates::STATE_CHECKED)
|
|
|
|
aName.AssignLiteral("uncheck");
|
2009-03-09 08:10:40 -07:00
|
|
|
else if (state & nsIAccessibleStates::STATE_MIXED)
|
|
|
|
aName.AssignLiteral("cycle");
|
2007-03-22 10:30:00 -07:00
|
|
|
else
|
|
|
|
aName.AssignLiteral("check");
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
return NS_ERROR_INVALID_ARG;
|
|
|
|
}
|
|
|
|
|
2010-01-25 07:09:25 -08:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsHTMLCheckboxAccessible::DoAction(PRUint8 aIndex)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
2010-01-25 07:09:25 -08:00
|
|
|
if (aIndex != 0)
|
|
|
|
return NS_ERROR_INVALID_ARG;
|
|
|
|
|
|
|
|
DoCommand();
|
|
|
|
return NS_OK;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
2008-11-03 19:37:46 -08:00
|
|
|
nsresult
|
|
|
|
nsHTMLCheckboxAccessible::GetStateInternal(PRUint32 *aState,
|
|
|
|
PRUint32 *aExtraState)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
2008-11-03 19:37:46 -08:00
|
|
|
nsresult rv = nsFormControlAccessible::GetStateInternal(aState, aExtraState);
|
2008-11-26 20:04:05 -08:00
|
|
|
NS_ENSURE_A11Y_SUCCESS(rv, rv);
|
2007-04-02 08:56:24 -07:00
|
|
|
|
2007-05-06 07:50:03 -07:00
|
|
|
*aState |= nsIAccessibleStates::STATE_CHECKABLE;
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
PRBool checked = PR_FALSE; // Radio buttons and check boxes can be checked
|
2009-02-11 00:40:27 -08:00
|
|
|
PRBool mixed = PR_FALSE; // or mixed.
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDOMNSHTMLInputElement>
|
|
|
|
html5CheckboxElement(do_QueryInterface(mDOMNode));
|
|
|
|
|
|
|
|
if (html5CheckboxElement) {
|
|
|
|
html5CheckboxElement->GetIndeterminate(&mixed);
|
|
|
|
|
|
|
|
if (mixed) {
|
|
|
|
*aState |= nsIAccessibleStates::STATE_MIXED;
|
|
|
|
return NS_OK; // indeterminate can't be checked at the same time.
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
nsCOMPtr<nsIDOMHTMLInputElement> htmlCheckboxElement(do_QueryInterface(mDOMNode));
|
2009-02-11 00:40:27 -08:00
|
|
|
if (htmlCheckboxElement) {
|
2007-03-22 10:30:00 -07:00
|
|
|
htmlCheckboxElement->GetChecked(&checked);
|
2009-02-11 00:40:27 -08:00
|
|
|
|
|
|
|
if (checked)
|
|
|
|
*aState |= nsIAccessibleStates::STATE_CHECKED;
|
|
|
|
}
|
2007-04-02 08:56:24 -07:00
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2010-01-06 02:36:50 -08:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// nsHTMLRadioButtonAccessible
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
nsHTMLRadioButtonAccessible::nsHTMLRadioButtonAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell):
|
|
|
|
nsRadioButtonAccessible(aNode, aShell)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2008-11-03 19:37:46 -08:00
|
|
|
nsresult
|
|
|
|
nsHTMLRadioButtonAccessible::GetStateInternal(PRUint32 *aState,
|
|
|
|
PRUint32 *aExtraState)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
2008-11-03 19:37:46 -08:00
|
|
|
nsresult rv = nsAccessibleWrap::GetStateInternal(aState, aExtraState);
|
2008-11-26 20:04:05 -08:00
|
|
|
NS_ENSURE_A11Y_SUCCESS(rv, rv);
|
2007-04-02 08:56:24 -07:00
|
|
|
|
2007-05-06 07:50:03 -07:00
|
|
|
*aState |= nsIAccessibleStates::STATE_CHECKABLE;
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
PRBool checked = PR_FALSE; // Radio buttons and check boxes can be checked
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDOMHTMLInputElement> htmlRadioElement(do_QueryInterface(mDOMNode));
|
2007-04-02 08:56:24 -07:00
|
|
|
if (htmlRadioElement)
|
2007-03-22 10:30:00 -07:00
|
|
|
htmlRadioElement->GetChecked(&checked);
|
|
|
|
|
2007-04-02 08:56:24 -07:00
|
|
|
if (checked)
|
|
|
|
*aState |= nsIAccessibleStates::STATE_CHECKED;
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2010-01-06 02:36:50 -08:00
|
|
|
void
|
|
|
|
nsHTMLRadioButtonAccessible::GetPositionAndSizeInternal(PRInt32 *aPosInSet,
|
|
|
|
PRInt32 *aSetSize)
|
2007-03-27 05:17:11 -07:00
|
|
|
{
|
|
|
|
nsAutoString nsURI;
|
|
|
|
mDOMNode->GetNamespaceURI(nsURI);
|
|
|
|
nsAutoString tagName;
|
|
|
|
mDOMNode->GetLocalName(tagName);
|
|
|
|
|
2007-04-03 01:27:43 -07:00
|
|
|
nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
|
|
|
|
|
|
|
|
nsAutoString type;
|
|
|
|
content->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::type, type);
|
|
|
|
nsAutoString name;
|
|
|
|
content->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::name, name);
|
|
|
|
|
2007-04-06 08:44:46 -07:00
|
|
|
nsCOMPtr<nsIDOMNodeList> inputs;
|
|
|
|
|
2007-03-27 05:17:11 -07:00
|
|
|
nsCOMPtr<nsIDOMHTMLInputElement> radio(do_QueryInterface(mDOMNode));
|
|
|
|
nsCOMPtr<nsIDOMHTMLFormElement> form;
|
|
|
|
radio->GetForm(getter_AddRefs(form));
|
2007-04-06 08:44:46 -07:00
|
|
|
if (form) {
|
|
|
|
form->GetElementsByTagNameNS(nsURI, tagName, getter_AddRefs(inputs));
|
|
|
|
} else {
|
|
|
|
nsCOMPtr<nsIDOMDocument> document;
|
|
|
|
mDOMNode->GetOwnerDocument(getter_AddRefs(document));
|
|
|
|
if (document)
|
|
|
|
document->GetElementsByTagNameNS(nsURI, tagName, getter_AddRefs(inputs));
|
|
|
|
}
|
2007-03-27 05:17:11 -07:00
|
|
|
|
2010-01-06 02:36:50 -08:00
|
|
|
NS_ENSURE_TRUE(inputs, );
|
2007-03-27 05:17:11 -07:00
|
|
|
|
2007-04-03 01:27:43 -07:00
|
|
|
PRUint32 inputsCount = 0;
|
|
|
|
inputs->GetLength(&inputsCount);
|
2007-03-27 05:17:11 -07:00
|
|
|
|
2010-01-06 02:36:50 -08:00
|
|
|
// Compute posinset and setsize.
|
2007-03-27 05:17:11 -07:00
|
|
|
PRInt32 indexOf = 0;
|
2007-04-03 01:27:43 -07:00
|
|
|
PRInt32 count = 0;
|
|
|
|
|
|
|
|
for (PRUint32 index = 0; index < inputsCount; index++) {
|
|
|
|
nsCOMPtr<nsIDOMNode> itemNode;
|
|
|
|
inputs->Item(index, getter_AddRefs(itemNode));
|
|
|
|
|
|
|
|
nsCOMPtr<nsIContent> item(do_QueryInterface(itemNode));
|
|
|
|
if (item &&
|
|
|
|
item->AttrValueIs(kNameSpaceID_None, nsAccessibilityAtoms::type,
|
|
|
|
type, eCaseMatters) &&
|
|
|
|
item->AttrValueIs(kNameSpaceID_None, nsAccessibilityAtoms::name,
|
|
|
|
name, eCaseMatters)) {
|
|
|
|
|
|
|
|
count++;
|
|
|
|
|
|
|
|
if (itemNode == mDOMNode)
|
|
|
|
indexOf = count;
|
2007-03-27 05:17:11 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-01-06 02:36:50 -08:00
|
|
|
*aPosInSet = indexOf;
|
|
|
|
*aSetSize = count;
|
2007-03-27 05:17:11 -07:00
|
|
|
}
|
|
|
|
|
2010-01-06 02:36:50 -08:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// nsHTMLButtonAccessible
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
nsHTMLButtonAccessible::nsHTMLButtonAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell):
|
2007-05-01 10:08:26 -07:00
|
|
|
nsHyperTextAccessibleWrap(aNode, aShell)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP nsHTMLButtonAccessible::GetNumActions(PRUint8 *_retval)
|
|
|
|
{
|
|
|
|
*_retval = 1;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP nsHTMLButtonAccessible::GetActionName(PRUint8 aIndex, nsAString& aName)
|
|
|
|
{
|
|
|
|
if (aIndex == eAction_Click) {
|
|
|
|
aName.AssignLiteral("press");
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
return NS_ERROR_INVALID_ARG;
|
|
|
|
}
|
|
|
|
|
2010-01-25 07:09:25 -08:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsHTMLButtonAccessible::DoAction(PRUint8 aIndex)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
2010-01-25 07:09:25 -08:00
|
|
|
if (aIndex != eAction_Click)
|
|
|
|
return NS_ERROR_INVALID_ARG;
|
|
|
|
|
|
|
|
DoCommand();
|
|
|
|
return NS_OK;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
2008-11-03 19:37:46 -08:00
|
|
|
nsresult
|
|
|
|
nsHTMLButtonAccessible::GetStateInternal(PRUint32 *aState,
|
|
|
|
PRUint32 *aExtraState)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
2008-11-03 19:37:46 -08:00
|
|
|
nsresult rv = nsHyperTextAccessibleWrap::GetStateInternal(aState,
|
|
|
|
aExtraState);
|
2008-11-26 20:04:05 -08:00
|
|
|
NS_ENSURE_A11Y_SUCCESS(rv, rv);
|
2008-02-11 04:12:17 -08:00
|
|
|
|
|
|
|
nsCOMPtr<nsIDOMElement> element(do_QueryInterface(mDOMNode));
|
|
|
|
NS_ENSURE_TRUE(element, NS_ERROR_FAILURE);
|
2007-04-02 08:56:24 -07:00
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
nsAutoString buttonType;
|
|
|
|
element->GetAttribute(NS_LITERAL_STRING("type"), buttonType);
|
|
|
|
if (buttonType.LowerCaseEqualsLiteral("submit"))
|
2007-04-02 08:56:24 -07:00
|
|
|
*aState |= nsIAccessibleStates::STATE_DEFAULT;
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2009-03-07 07:38:58 -08:00
|
|
|
nsresult
|
|
|
|
nsHTMLButtonAccessible::GetRoleInternal(PRUint32 *aRole)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
2009-03-07 07:38:58 -08:00
|
|
|
*aRole = nsIAccessibleRole::ROLE_PUSHBUTTON;
|
2007-03-22 10:30:00 -07:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2008-10-10 05:26:55 -07:00
|
|
|
nsresult
|
|
|
|
nsHTMLButtonAccessible::GetNameInternal(nsAString& aName)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
2009-06-24 16:18:46 -07:00
|
|
|
nsAccessible::GetNameInternal(aName);
|
2008-10-14 01:27:02 -07:00
|
|
|
if (!aName.IsEmpty())
|
|
|
|
return NS_OK;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
|
|
|
|
|
|
|
|
// No name from HTML or ARIA
|
2007-03-22 10:30:00 -07:00
|
|
|
nsAutoString name;
|
2008-10-14 01:27:02 -07:00
|
|
|
if (!content->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::value,
|
|
|
|
name) &&
|
|
|
|
!content->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::alt,
|
|
|
|
name)) {
|
|
|
|
// Use the button's (default) label if nothing else works
|
|
|
|
nsIFrame* frame = GetFrame();
|
|
|
|
if (frame) {
|
2009-01-12 11:20:59 -08:00
|
|
|
nsIFormControlFrame* fcFrame = do_QueryFrame(frame);
|
2008-10-14 01:27:02 -07:00
|
|
|
if (fcFrame)
|
|
|
|
fcFrame->GetFormProperty(nsAccessibilityAtoms::defaultLabel, name);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-10-14 01:27:02 -07:00
|
|
|
if (name.IsEmpty() &&
|
|
|
|
!content->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::src,
|
|
|
|
name)) {
|
|
|
|
content->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::data, name);
|
|
|
|
}
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
name.CompressWhitespace();
|
|
|
|
aName = name;
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ----- HTML 4 Button: can contain arbitrary HTML content -----
|
|
|
|
|
|
|
|
nsHTML4ButtonAccessible::nsHTML4ButtonAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell):
|
2007-05-01 10:08:26 -07:00
|
|
|
nsHyperTextAccessibleWrap(aNode, aShell)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP nsHTML4ButtonAccessible::GetNumActions(PRUint8 *_retval)
|
|
|
|
{
|
|
|
|
*_retval = 1;
|
|
|
|
return NS_OK;;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP nsHTML4ButtonAccessible::GetActionName(PRUint8 aIndex, nsAString& aName)
|
|
|
|
{
|
|
|
|
if (aIndex == eAction_Click) {
|
|
|
|
aName.AssignLiteral("press");
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
return NS_ERROR_INVALID_ARG;
|
|
|
|
}
|
|
|
|
|
2010-01-25 07:09:25 -08:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsHTML4ButtonAccessible::DoAction(PRUint8 aIndex)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
2010-01-25 07:09:25 -08:00
|
|
|
if (aIndex != 0)
|
|
|
|
return NS_ERROR_INVALID_ARG;
|
|
|
|
|
|
|
|
DoCommand();
|
|
|
|
return NS_OK;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
2009-03-07 07:38:58 -08:00
|
|
|
nsresult
|
|
|
|
nsHTML4ButtonAccessible::GetRoleInternal(PRUint32 *aRole)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
2009-03-07 07:38:58 -08:00
|
|
|
*aRole = nsIAccessibleRole::ROLE_PUSHBUTTON;
|
2007-03-22 10:30:00 -07:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2008-11-03 19:37:46 -08:00
|
|
|
nsresult
|
|
|
|
nsHTML4ButtonAccessible::GetStateInternal(PRUint32 *aState,
|
|
|
|
PRUint32 *aExtraState)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
2008-11-03 19:37:46 -08:00
|
|
|
nsresult rv = nsHyperTextAccessibleWrap::GetStateInternal(aState,
|
|
|
|
aExtraState);
|
2008-11-26 20:04:05 -08:00
|
|
|
NS_ENSURE_A11Y_SUCCESS(rv, rv);
|
2008-02-11 04:12:17 -08:00
|
|
|
|
|
|
|
nsCOMPtr<nsIDOMElement> element(do_QueryInterface(mDOMNode));
|
|
|
|
NS_ASSERTION(element, "No element for button's dom node!");
|
2007-04-02 08:56:24 -07:00
|
|
|
|
|
|
|
*aState |= nsIAccessibleStates::STATE_FOCUSABLE;
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
nsAutoString buttonType;
|
|
|
|
element->GetAttribute(NS_LITERAL_STRING("type"), buttonType);
|
|
|
|
if (buttonType.LowerCaseEqualsLiteral("submit"))
|
2007-04-02 08:56:24 -07:00
|
|
|
*aState |= nsIAccessibleStates::STATE_DEFAULT;
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
// --- textfield -----
|
|
|
|
|
|
|
|
nsHTMLTextFieldAccessible::nsHTMLTextFieldAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell):
|
2007-05-01 10:08:26 -07:00
|
|
|
nsHyperTextAccessibleWrap(aNode, aShell)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2007-11-09 11:27:07 -08:00
|
|
|
NS_IMPL_ISUPPORTS_INHERITED3(nsHTMLTextFieldAccessible, nsAccessible, nsHyperTextAccessible, nsIAccessibleText, nsIAccessibleEditableText)
|
|
|
|
|
2009-03-07 07:38:58 -08:00
|
|
|
nsresult
|
|
|
|
nsHTMLTextFieldAccessible::GetRoleInternal(PRUint32 *aRole)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
*aRole = nsIAccessibleRole::ROLE_ENTRY;
|
|
|
|
nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
|
|
|
|
if (content &&
|
|
|
|
content->AttrValueIs(kNameSpaceID_None, nsAccessibilityAtoms::type,
|
|
|
|
nsAccessibilityAtoms::password, eIgnoreCase)) {
|
|
|
|
*aRole = nsIAccessibleRole::ROLE_PASSWORD_TEXT;
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2008-10-14 01:27:02 -07:00
|
|
|
nsresult
|
|
|
|
nsHTMLTextFieldAccessible::GetNameInternal(nsAString& aName)
|
2007-06-14 18:50:37 -07:00
|
|
|
{
|
2008-10-14 01:27:02 -07:00
|
|
|
nsresult rv = nsAccessible::GetNameInternal(aName);
|
2008-10-10 05:26:55 -07:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
if (!aName.IsEmpty())
|
|
|
|
return NS_OK;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIContent> content = do_QueryInterface(mDOMNode);
|
2008-10-14 01:27:02 -07:00
|
|
|
if (!content->GetBindingParent())
|
|
|
|
return NS_OK;
|
2007-06-14 18:50:37 -07:00
|
|
|
|
2008-10-14 01:27:02 -07:00
|
|
|
// XXX: bug 459640
|
2007-06-14 18:50:37 -07:00
|
|
|
// There's a binding parent.
|
|
|
|
// This means we're part of another control, so use parent accessible for name.
|
|
|
|
// This ensures that a textbox inside of a XUL widget gets
|
|
|
|
// an accessible name.
|
|
|
|
nsCOMPtr<nsIAccessible> parent;
|
|
|
|
rv = GetParent(getter_AddRefs(parent));
|
|
|
|
return parent ? parent->GetName(aName) : rv;
|
|
|
|
}
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
NS_IMETHODIMP nsHTMLTextFieldAccessible::GetValue(nsAString& _retval)
|
|
|
|
{
|
|
|
|
PRUint32 state;
|
2008-11-03 19:37:46 -08:00
|
|
|
nsresult rv = GetStateInternal(&state, nsnull);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
if (state & nsIAccessibleStates::STATE_PROTECTED) // Don't return password text!
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDOMHTMLTextAreaElement> textArea(do_QueryInterface(mDOMNode));
|
|
|
|
if (textArea) {
|
|
|
|
return textArea->GetValue(_retval);
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDOMHTMLInputElement> inputElement(do_QueryInterface(mDOMNode));
|
|
|
|
if (inputElement) {
|
|
|
|
return inputElement->GetValue(_retval);
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
2008-11-03 19:37:46 -08:00
|
|
|
nsresult
|
|
|
|
nsHTMLTextFieldAccessible::GetStateInternal(PRUint32 *aState,
|
|
|
|
PRUint32 *aExtraState)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
2008-11-03 19:37:46 -08:00
|
|
|
nsresult rv = nsHyperTextAccessibleWrap::GetStateInternal(aState,
|
|
|
|
aExtraState);
|
2008-11-26 20:04:05 -08:00
|
|
|
NS_ENSURE_A11Y_SUCCESS(rv, rv);
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
// can be focusable, focused, protected. readonly, unavailable, selected
|
|
|
|
nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
|
|
|
|
NS_ASSERTION(content, "Should not have gotten here if upcalled GetExtState() succeeded");
|
|
|
|
|
|
|
|
if (content->AttrValueIs(kNameSpaceID_None, nsAccessibilityAtoms::type,
|
|
|
|
nsAccessibilityAtoms::password, eIgnoreCase)) {
|
|
|
|
*aState |= nsIAccessibleStates::STATE_PROTECTED;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
nsCOMPtr<nsIAccessible> parent;
|
|
|
|
GetParent(getter_AddRefs(parent));
|
2008-10-17 03:10:43 -07:00
|
|
|
if (nsAccUtils::Role(parent) == nsIAccessibleRole::ROLE_AUTOCOMPLETE)
|
2007-03-22 10:30:00 -07:00
|
|
|
*aState |= nsIAccessibleStates::STATE_HASPOPUP;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (content->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::readonly)) {
|
|
|
|
*aState |= nsIAccessibleStates::STATE_READONLY;
|
|
|
|
}
|
|
|
|
|
2008-07-02 01:42:58 -07:00
|
|
|
if (!aExtraState)
|
2007-04-02 08:56:24 -07:00
|
|
|
return NS_OK;
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2007-04-05 15:14:08 -07:00
|
|
|
nsCOMPtr<nsIDOMHTMLInputElement> htmlInput(do_QueryInterface(mDOMNode));
|
2007-03-22 10:30:00 -07:00
|
|
|
// Is it an <input> or a <textarea> ?
|
2007-06-04 01:16:04 -07:00
|
|
|
if (htmlInput) {
|
|
|
|
*aExtraState |= nsIAccessibleStates::EXT_STATE_SINGLE_LINE;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
*aExtraState |= nsIAccessibleStates::EXT_STATE_MULTI_LINE;
|
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2008-07-02 01:42:58 -07:00
|
|
|
if (!(*aExtraState & nsIAccessibleStates::EXT_STATE_EDITABLE))
|
|
|
|
return NS_OK;
|
|
|
|
|
2007-04-05 15:14:08 -07:00
|
|
|
nsCOMPtr<nsIContent> bindingContent = content->GetBindingParent();
|
|
|
|
if (bindingContent &&
|
|
|
|
bindingContent->NodeInfo()->Equals(nsAccessibilityAtoms::textbox,
|
|
|
|
kNameSpaceID_XUL) &&
|
|
|
|
bindingContent->AttrValueIs(kNameSpaceID_None, nsAccessibilityAtoms::type,
|
|
|
|
nsAccessibilityAtoms::autocomplete,
|
|
|
|
eIgnoreCase)) {
|
|
|
|
// If parent is XUL textbox and value of @type attribute is "autocomplete",
|
|
|
|
// then this accessible supports autocompletion.
|
|
|
|
*aExtraState |= nsIAccessibleStates::EXT_STATE_SUPPORTS_AUTOCOMPLETION;
|
|
|
|
} else if (gIsFormFillEnabled && htmlInput &&
|
|
|
|
!(*aState & nsIAccessibleStates::STATE_PROTECTED)) {
|
|
|
|
// Check to see if autocompletion is allowed on this input. We don't expose
|
|
|
|
// it for password fields even though the entire password can be remembered
|
|
|
|
// for a page if the user asks it to be. However, the kind of autocomplete
|
|
|
|
// we're talking here is based on what the user types, where a popup of
|
|
|
|
// possible choices comes up.
|
|
|
|
nsAutoString autocomplete;
|
|
|
|
content->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::autocomplete,
|
|
|
|
autocomplete);
|
|
|
|
|
|
|
|
if (!autocomplete.LowerCaseEqualsLiteral("off")) {
|
|
|
|
nsCOMPtr<nsIDOMHTMLFormElement> form;
|
|
|
|
htmlInput->GetForm(getter_AddRefs(form));
|
|
|
|
nsCOMPtr<nsIContent> formContent(do_QueryInterface(form));
|
|
|
|
if (formContent) {
|
|
|
|
formContent->GetAttr(kNameSpaceID_None,
|
2007-12-11 18:10:26 -08:00
|
|
|
nsAccessibilityAtoms::autocomplete, autocomplete);
|
2007-04-05 14:52:03 -07:00
|
|
|
}
|
2007-04-05 15:14:08 -07:00
|
|
|
|
|
|
|
if (!formContent || !autocomplete.LowerCaseEqualsLiteral("off"))
|
|
|
|
*aExtraState |= nsIAccessibleStates::EXT_STATE_SUPPORTS_AUTOCOMPLETION;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP nsHTMLTextFieldAccessible::GetNumActions(PRUint8 *_retval)
|
|
|
|
{
|
|
|
|
*_retval = 1;
|
|
|
|
return NS_OK;;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP nsHTMLTextFieldAccessible::GetActionName(PRUint8 aIndex, nsAString& aName)
|
|
|
|
{
|
|
|
|
if (aIndex == eAction_Click) {
|
|
|
|
aName.AssignLiteral("activate");
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
return NS_ERROR_INVALID_ARG;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP nsHTMLTextFieldAccessible::DoAction(PRUint8 index)
|
|
|
|
{
|
|
|
|
if (index == 0) {
|
2007-05-07 11:51:36 -07:00
|
|
|
nsCOMPtr<nsIDOMNSHTMLElement> element(do_QueryInterface(mDOMNode));
|
|
|
|
if ( element ) {
|
|
|
|
return element->Focus();
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
return NS_ERROR_INVALID_ARG;
|
|
|
|
}
|
|
|
|
|
2007-08-14 09:25:24 -07:00
|
|
|
NS_IMETHODIMP nsHTMLTextFieldAccessible::GetAssociatedEditor(nsIEditor **aEditor)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
2007-08-14 09:25:24 -07:00
|
|
|
*aEditor = nsnull;
|
2007-03-22 10:30:00 -07:00
|
|
|
nsCOMPtr<nsIDOMNSEditableElement> editableElt(do_QueryInterface(mDOMNode));
|
2007-08-14 09:25:24 -07:00
|
|
|
NS_ENSURE_TRUE(editableElt, NS_ERROR_FAILURE);
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2007-07-24 23:24:00 -07:00
|
|
|
// nsGenericHTMLElement::GetEditor has a security check.
|
|
|
|
// Make sure we're not restricted by the permissions of
|
|
|
|
// whatever script is currently running.
|
|
|
|
nsCOMPtr<nsIJSContextStack> stack =
|
|
|
|
do_GetService("@mozilla.org/js/xpc/ContextStack;1");
|
|
|
|
PRBool pushed = stack && NS_SUCCEEDED(stack->Push(nsnull));
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
nsCOMPtr<nsIEditor> editor;
|
2007-08-14 09:25:24 -07:00
|
|
|
nsresult rv = editableElt->GetEditor(aEditor);
|
2007-07-24 23:24:00 -07:00
|
|
|
|
|
|
|
if (pushed) {
|
|
|
|
JSContext* cx;
|
|
|
|
stack->Pop(&cx);
|
|
|
|
NS_ASSERTION(!cx, "context should be null");
|
|
|
|
}
|
2007-08-14 09:25:24 -07:00
|
|
|
|
|
|
|
return rv;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// --- groupbox -----
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The HTML for this is <fieldset> <legend>box-title</legend> form elements </fieldset>
|
|
|
|
*/
|
|
|
|
|
|
|
|
nsHTMLGroupboxAccessible::nsHTMLGroupboxAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell):
|
2007-06-30 13:06:13 -07:00
|
|
|
nsHyperTextAccessibleWrap(aNode, aShell)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2009-03-07 07:38:58 -08:00
|
|
|
nsresult
|
|
|
|
nsHTMLGroupboxAccessible::GetRoleInternal(PRUint32 *aRole)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
2009-03-07 07:38:58 -08:00
|
|
|
*aRole = nsIAccessibleRole::ROLE_GROUPING;
|
2007-03-22 10:30:00 -07:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2007-06-30 13:06:13 -07:00
|
|
|
nsIContent* nsHTMLGroupboxAccessible::GetLegend()
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
2007-06-30 13:06:13 -07:00
|
|
|
nsCOMPtr<nsIContent> content = do_QueryInterface(mDOMNode);
|
|
|
|
NS_ENSURE_TRUE(content, nsnull);
|
|
|
|
|
|
|
|
nsresult count = 0;
|
|
|
|
nsIContent *testLegendContent;
|
|
|
|
while ((testLegendContent = content->GetChildAt(count ++ )) != nsnull) {
|
|
|
|
if (testLegendContent->NodeInfo()->Equals(nsAccessibilityAtoms::legend,
|
|
|
|
content->GetNameSpaceID())) {
|
|
|
|
// Either XHTML namespace or no namespace
|
|
|
|
return testLegendContent;
|
|
|
|
}
|
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2007-06-30 13:06:13 -07:00
|
|
|
return nsnull;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
2008-10-10 05:26:55 -07:00
|
|
|
nsresult
|
|
|
|
nsHTMLGroupboxAccessible::GetNameInternal(nsAString& aName)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
2008-10-10 05:26:55 -07:00
|
|
|
nsresult rv = nsAccessible::GetNameInternal(aName);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2008-08-24 09:45:56 -07:00
|
|
|
|
2008-10-10 05:26:55 -07:00
|
|
|
if (!aName.IsEmpty())
|
|
|
|
return NS_OK;
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2007-06-30 13:06:13 -07:00
|
|
|
nsIContent *legendContent = GetLegend();
|
|
|
|
if (legendContent) {
|
2009-02-18 23:06:14 -08:00
|
|
|
return nsTextEquivUtils::
|
|
|
|
AppendTextEquivFromContent(this, legendContent, &aName);
|
2007-06-30 13:06:13 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2009-02-10 02:03:30 -08:00
|
|
|
nsHTMLGroupboxAccessible::GetRelationByType(PRUint32 aRelationType,
|
|
|
|
nsIAccessibleRelation **aRelation)
|
2007-06-30 13:06:13 -07:00
|
|
|
{
|
2009-02-10 02:03:30 -08:00
|
|
|
nsresult rv = nsHyperTextAccessibleWrap::GetRelationByType(aRelationType,
|
|
|
|
aRelation);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2007-06-30 13:06:13 -07:00
|
|
|
|
|
|
|
if (aRelationType == nsIAccessibleRelation::RELATION_LABELLED_BY) {
|
|
|
|
// No override for label, so use <legend> for this <fieldset>
|
2009-02-10 02:03:30 -08:00
|
|
|
return nsRelUtils::
|
|
|
|
AddTargetFromContent(aRelationType, aRelation, GetLegend());
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
2007-06-30 13:06:13 -07:00
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2009-03-07 07:38:58 -08:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// nsHTMLLegendAccessible
|
|
|
|
|
2007-06-30 13:06:13 -07:00
|
|
|
nsHTMLLegendAccessible::nsHTMLLegendAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell):
|
|
|
|
nsHyperTextAccessibleWrap(aNode, aShell)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2009-02-10 02:03:30 -08:00
|
|
|
nsHTMLLegendAccessible::GetRelationByType(PRUint32 aRelationType,
|
|
|
|
nsIAccessibleRelation **aRelation)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
2009-02-10 02:03:30 -08:00
|
|
|
nsresult rv = nsHyperTextAccessibleWrap::
|
|
|
|
GetRelationByType(aRelationType, aRelation);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2007-06-30 13:06:13 -07:00
|
|
|
if (aRelationType == nsIAccessibleRelation::RELATION_LABEL_FOR) {
|
|
|
|
// Look for groupbox parent
|
2010-01-11 06:14:06 -08:00
|
|
|
nsAccessible* groupbox = GetParent();
|
|
|
|
|
|
|
|
if (nsAccUtils::Role(groupbox) == nsIAccessibleRole::ROLE_GROUPING) {
|
2009-02-10 02:03:30 -08:00
|
|
|
// XXX: if group box exposes more than one relation of the given type
|
|
|
|
// then we fail.
|
|
|
|
nsCOMPtr<nsIAccessible> testLabelAccessible =
|
2010-01-11 06:14:06 -08:00
|
|
|
nsRelUtils::GetRelatedAccessible(groupbox,
|
2009-02-10 02:03:30 -08:00
|
|
|
nsIAccessibleRelation::RELATION_LABELLED_BY);
|
|
|
|
|
2007-06-30 13:06:13 -07:00
|
|
|
if (testLabelAccessible == this) {
|
2009-02-10 02:03:30 -08:00
|
|
|
// We're the first child of the parent groupbox, see
|
|
|
|
// nsHTMLGroupboxAccessible::GetRelationByType().
|
|
|
|
return nsRelUtils::
|
2010-01-11 06:14:06 -08:00
|
|
|
AddTarget(aRelationType, aRelation, groupbox);
|
2007-06-30 13:06:13 -07:00
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
}
|
2007-06-30 13:06:13 -07:00
|
|
|
|
|
|
|
return NS_OK;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
2009-03-07 07:38:58 -08:00
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsHTMLLegendAccessible::GetRoleInternal(PRUint32 *aRole)
|
|
|
|
{
|
|
|
|
*aRole = nsIAccessibleRole::ROLE_LABEL;
|
|
|
|
return NS_OK;
|
|
|
|
}
|