Bug 340825. New ATK, implement nsIAccessible value for all platforms and for DHTM, via nsAccessible. r=ginn.chen

This commit is contained in:
aaronleventhal%moonset.net 2006-06-15 16:55:32 +00:00
parent e88a1da51d
commit d6a103f39d
17 changed files with 208 additions and 112 deletions

View File

@ -100,7 +100,7 @@ interface nsIAccessible : nsISupports
* Accessible value -- a number or a secondary text equivalent for this node
* Widgets that use xhtml2:role can force a value using the valuenow attribute
*/
readonly attribute AString finalValue;
readonly attribute AString value;
/**
* Accessible description -- long text associated with this node

View File

@ -44,14 +44,8 @@ interface nsIAccessibleValue : nsISupports
{
readonly attribute double maximumValue;
readonly attribute double minimumValue;
readonly attribute double currentValue;
/**
* We want to be able to return a success condition of the value
* getting set. ie if the value is not within the interval of
* minimumValue-maximumValue
*/
boolean setCurrentValue (in double value);
attribute double currentValue;
readonly attribute double minimumIncrement;
};
/*

View File

@ -50,6 +50,9 @@ valueInterfaceInitCB(AtkValueIface *aIface)
aIface->get_current_value = getCurrentValueCB;
aIface->get_maximum_value = getMaximumValueCB;
aIface->get_minimum_value = getMinimumValueCB;
#ifdef USE_ATK_VALUE_MINIMUMINCREMENT
aIface->get_minimum_increment = getMinimumIncrementCB;
#endif
aIface->set_current_value = setCurrentValueCB;
}
@ -116,6 +119,29 @@ getMinimumValueCB(AtkValue *obj, GValue *value)
g_value_set_double (value, accDouble);
}
#ifdef USE_ATK_VALUE_MINIMUMINCREMENT
void
getMinimumIncrementCB(AtkValue *obj, GValue *minimumIncrement)
{
nsAccessibleWrap *accWrap = GetAccessibleWrap(ATK_OBJECT(obj));
if (!accWrap)
return;
nsCOMPtr<nsIAccessibleValue> accValue;
accWrap->QueryInterface(NS_GET_IID(nsIAccessibleValue),
getter_AddRefs(accValue));
if (!accValue)
return;
memset (value, 0, sizeof (GValue));
double accDouble;
if (NS_FAILED(accValue->GetMinimumIncrement(&accDouble)))
return;
g_value_init (minimumIncrement, G_TYPE_DOUBLE);
g_value_set_double (minimumIncrement, accDouble);
}
#endif
gboolean
setCurrentValueCB(AtkValue *obj, const GValue *value)
{
@ -127,9 +153,6 @@ setCurrentValueCB(AtkValue *obj, const GValue *value)
getter_AddRefs(accValue));
NS_ENSURE_TRUE(accValue, FALSE);
PRBool aBool;
double accDouble;
accDouble = g_value_get_double (value);
accValue->SetCurrentValue(accDouble, &aBool);
return aBool;
double accDouble =g_value_get_double (value);
return !NS_FAILED(accValue->SetCurrentValue(accDouble));
}

View File

@ -51,6 +51,9 @@ void valueInterfaceInitCB(AtkValueIface *aIface);
void getCurrentValueCB(AtkValue *obj, GValue *value);
void getMaximumValueCB(AtkValue *obj, GValue *value);
void getMinimumValueCB(AtkValue *obj, GValue *value);
#ifdef USE_ATK_VALUE_MINIMUMINCREMENT
void getMinimumIncrementCB(AtkValue *obj, GValue *minIncrement);
#endif
gboolean setCurrentValueCB(AtkValue *obj, const GValue *value);
G_END_DECLS

View File

@ -44,62 +44,6 @@
#include "nsIDOMHTMLInputElement.h"
#include "nsIDOMXULTextboxElement.h"
NS_IMPL_ISUPPORTS_INHERITED1(nsXULProgressMeterAccessibleWrap, nsXULProgressMeterAccessible, nsIAccessibleValue)
nsXULProgressMeterAccessibleWrap::nsXULProgressMeterAccessibleWrap(nsIDOMNode* aNode, nsIWeakReference* aShell):
nsXULProgressMeterAccessible(aNode, aShell)
{
}
/* readonly attribute double maximumValue; */
NS_IMETHODIMP nsXULProgressMeterAccessibleWrap::GetMaximumValue(double *aMaximumValue)
{
*aMaximumValue = 1; // 100% = 1;
return NS_OK;
}
/* readonly attribute double minimumValue; */
NS_IMETHODIMP nsXULProgressMeterAccessibleWrap::GetMinimumValue(double *aMinimumValue)
{
*aMinimumValue = 0;
return NS_OK;
}
/* readonly attribute double currentValue; */
NS_IMETHODIMP nsXULProgressMeterAccessibleWrap::GetCurrentValue(double *aCurrentValue)
{
nsAutoString currentValue;
GetValue(currentValue);
PRInt32 error;
*aCurrentValue = currentValue.ToFloat(&error) / 100;
return NS_OK;
}
/* boolean setCurrentValue (in double value); */
NS_IMETHODIMP nsXULProgressMeterAccessibleWrap::SetCurrentValue(double aValue, PRBool *_retval)
{
//Here I do not suppose the min/max are 0/1.00 because I want
// these part of code to be more extensible.
*_retval = PR_FALSE;
double min, max;
GetMinimumValue(&min);
GetMaximumValue(&max);
if (aValue > max || aValue < min)
return NS_ERROR_INVALID_ARG;
nsCOMPtr<nsIDOMElement> element(do_QueryInterface(mDOMNode));
NS_ASSERTION(element, "No element for DOM node!");
PRUint32 value = PRUint32(aValue * 100.0 + 0.5);
nsAutoString valueString;
valueString.AppendInt(value);
valueString.AppendLiteral("%");
if (NS_SUCCEEDED(element->SetAttribute(NS_LITERAL_STRING("value"), valueString))) {
*_retval = PR_TRUE;
return NS_OK;
}
return NS_ERROR_INVALID_ARG;
}
NS_IMPL_ISUPPORTS_INHERITED2(nsXULTextFieldAccessibleWrap, nsXULTextFieldAccessible, nsIAccessibleText, nsIAccessibleEditableText)
nsXULTextFieldAccessibleWrap::nsXULTextFieldAccessibleWrap(nsIDOMNode* aNode, nsIWeakReference* aShell):

View File

@ -44,17 +44,6 @@
#include "nsXULFormControlAccessible.h"
#include "nsAccessibleText.h"
class nsXULProgressMeterAccessibleWrap : public nsXULProgressMeterAccessible,
public nsIAccessibleValue
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIACCESSIBLEVALUE
nsXULProgressMeterAccessibleWrap(nsIDOMNode* aNode, nsIWeakReference* aShell);
};
class nsXULTextFieldAccessibleWrap : public nsXULTextFieldAccessible,
public nsAccessibleEditableText
{

View File

@ -153,3 +153,5 @@ ACCESSIBILITY_ATOM(required, "required")
ACCESSIBILITY_ATOM(role, "role")
ACCESSIBILITY_ATOM(selected, "selected")
ACCESSIBILITY_ATOM(valuenow, "valuenow") // For DHTML widget values
ACCESSIBILITY_ATOM(valuemin, "valuemin")
ACCESSIBILITY_ATOM(valuemax, "valuemax")

View File

@ -1321,7 +1321,7 @@ nsAccessibilityService::CreateXULProgressMeterAccessible(nsIDOMNode *aNode, nsIA
nsCOMPtr<nsIWeakReference> weakShell;
GetShellFromNode(aNode, getter_AddRefs(weakShell));
*_retval = new nsXULProgressMeterAccessibleWrap(aNode, weakShell);
*_retval = new nsXULProgressMeterAccessible(aNode, weakShell);
if (! *_retval)
return NS_ERROR_OUT_OF_MEMORY;

View File

@ -59,7 +59,7 @@
#include "nsISelectionController.h"
#include "nsIServiceManager.h"
#include "nsXPIDLString.h"
#include "prdtoa.h"
#include "nsIDOMComment.h"
#include "nsITextContent.h"
#include "nsIDOMHTMLImageElement.h"
@ -148,6 +148,13 @@ nsresult nsAccessible::QueryInterface(REFNSIID aIID, void** aInstancePtr)
}
}
if (aIID.Equals(NS_GET_IID(nsIAccessibleValue))) {
if (mRoleMapEntry && mRoleMapEntry->valueRule != eNoValue) {
*aInstancePtr = NS_STATIC_CAST(nsIAccessibleValue*, this);
NS_ADDREF_THIS();
}
}
return nsAccessNode::QueryInterface(aIID, aInstancePtr);
}
@ -1187,7 +1194,7 @@ nsresult nsAccessible::AppendNameFromAccessibleFor(nsIContent *aContent,
}
if (accessible) {
if (aFromValue) {
accessible->GetFinalValue(textEquivalent);
accessible->GetValue(textEquivalent);
}
else {
accessible->GetName(textEquivalent);
@ -1835,7 +1842,10 @@ NS_IMETHODIMP nsAccessible::GetFinalState(PRUint32 *aState)
return rv;
}
NS_IMETHODIMP nsAccessible::GetFinalValue(nsAString& aValue)
// Not implemented by this class
/* DOMString getValue (); */
NS_IMETHODIMP nsAccessible::GetValue(nsAString& aValue)
{
if (!mDOMNode) {
return NS_ERROR_FAILURE; // Node already shut down
@ -1850,15 +1860,112 @@ NS_IMETHODIMP nsAccessible::GetFinalValue(nsAString& aValue)
return NS_OK;
}
}
return GetValue(aValue);
return NS_OK;
}
// Not implemented by this class
/* DOMString getValue (); */
NS_IMETHODIMP nsAccessible::GetValue(nsAString& _retval)
NS_IMETHODIMP nsAccessible::GetMaximumValue(double *aMaximumValue)
{
return NS_ERROR_NOT_IMPLEMENTED;
*aMaximumValue = 0;
if (!mDOMNode) {
return NS_ERROR_FAILURE; // Node already shut down
}
if (mRoleMapEntry) {
if (mRoleMapEntry->valueRule == eNoValue) {
return NS_OK;
}
nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
nsAutoString valueMax;
if (content && content->GetAttr(kNameSpaceID_WAIProperties,
nsAccessibilityAtoms::valuemax, valueMax) &&
valueMax.IsEmpty() == PR_FALSE) {
*aMaximumValue = PR_strtod(NS_LossyConvertUTF16toASCII(valueMax).get(), nsnull);
return NS_OK;
}
}
return NS_ERROR_FAILURE; // No maximum
}
NS_IMETHODIMP nsAccessible::GetMinimumValue(double *aMinimumValue)
{
*aMinimumValue = 0;
if (!mDOMNode) {
return NS_ERROR_FAILURE; // Node already shut down
}
if (mRoleMapEntry) {
if (mRoleMapEntry->valueRule == eNoValue) {
return NS_OK;
}
nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
nsAutoString valueMin;
if (content && content->GetAttr(kNameSpaceID_WAIProperties,
nsAccessibilityAtoms::valuemin, valueMin) &&
valueMin.IsEmpty() == PR_FALSE) {
*aMinimumValue = PR_strtod(NS_LossyConvertUTF16toASCII(valueMin).get(), nsnull);
return NS_OK;
}
}
return NS_ERROR_FAILURE; // No minimum
}
NS_IMETHODIMP nsAccessible::GetMinimumIncrement(double *aMinIncrement)
{
*aMinIncrement = 0;
return NS_ERROR_NOT_IMPLEMENTED; // No mimimum increment in dynamic content spec right now
}
NS_IMETHODIMP nsAccessible::GetCurrentValue(double *aValue)
{
*aValue = 0;
if (!mDOMNode) {
return NS_ERROR_FAILURE; // Node already shut down
}
if (mRoleMapEntry) {
if (mRoleMapEntry->valueRule == eNoValue) {
return NS_OK;
}
nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
nsAutoString value;
if (content && content->GetAttr(kNameSpaceID_WAIProperties,
nsAccessibilityAtoms::valuenow, value) &&
value.IsEmpty() == PR_FALSE) {
*aValue = PR_strtod(NS_LossyConvertUTF16toASCII(value).get(), nsnull);
return NS_OK;
}
}
return NS_ERROR_FAILURE; // No value
}
NS_IMETHODIMP nsAccessible::SetCurrentValue(double aValue)
{
if (!mDOMNode) {
return NS_ERROR_FAILURE; // Node already shut down
}
if (mRoleMapEntry) {
if (mRoleMapEntry->valueRule == eNoValue) {
return NS_OK;
}
const PRUint32 kValueCannotChange = STATE_READONLY | STATE_UNAVAILABLE;
PRUint32 state;
if (NS_FAILED(GetFinalState(&state)) || (state & kValueCannotChange)) {
return NS_ERROR_FAILURE;
}
double minValue;
if (NS_SUCCEEDED(GetMinimumValue(&minValue)) && aValue < minValue) {
return NS_ERROR_INVALID_ARG;
}
double maxValue;
if (NS_SUCCEEDED(GetMaximumValue(&maxValue)) && aValue > maxValue) {
return NS_ERROR_INVALID_ARG;
}
nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
if (content) {
nsAutoString newValue;
newValue.AppendFloat(aValue);
return content->SetAttr(kNameSpaceID_WAIProperties,
nsAccessibilityAtoms::valuenow, newValue, PR_TRUE);
}
}
return NS_ERROR_FAILURE; // Not in a role that can accept value
}
/* void setName (in DOMString name); */

View File

@ -44,6 +44,7 @@
#include "nsIAccessible.h"
#include "nsPIAccessible.h"
#include "nsIAccessibleSelectable.h"
#include "nsIAccessibleValue.h"
#include "nsIDOMNodeList.h"
#include "nsINameSpaceManager.h"
#include "nsWeakReference.h"
@ -114,7 +115,8 @@ struct nsRoleMapEntry
class nsAccessible : public nsAccessNodeWrap,
public nsIAccessible,
public nsPIAccessible,
public nsIAccessibleSelectable
public nsIAccessibleSelectable,
public nsIAccessibleValue
{
public:
// to eliminate the confusion of "magic numbers" -- if ( 0 ){ foo; }
@ -129,14 +131,13 @@ public:
NS_DECL_NSIACCESSIBLE
NS_DECL_NSPIACCESSIBLE
NS_DECL_NSIACCESSIBLESELECTABLE
NS_DECL_NSIACCESSIBLEVALUE
// nsIAccessNode
NS_IMETHOD Init();
NS_IMETHOD Shutdown();
// Support GetFinalState(), GetFinalValue()
NS_IMETHOD GetState(PRUint32 *aState);
NS_IMETHOD GetValue(nsAString & aValue);
NS_IMETHOD GetState(PRUint32 *aState); // Must support GetFinalState()
#ifdef MOZ_ACCESSIBILITY_ATK
static nsresult GetParentBlockNode(nsIPresShell *aPresShell, nsIDOMNode *aCurrentNode, nsIDOMNode **aBlockNode);

View File

@ -734,7 +734,7 @@ NS_IMETHODIMP nsRootAccessible::HandleEvent(nsIDOMEvent* aEvent)
if (role == ROLE_PROGRESSBAR) {
// For progressmeter, fire EVENT_SHOW on 1st value change
nsAutoString value;
accessible->GetFinalValue(value);
accessible->GetValue(value);
if (value.EqualsLiteral("0%")) {
privAcc->FireToolkitEvent(nsIAccessibleEvent::EVENT_SHOW,
accessible, nsnull);

View File

@ -58,7 +58,6 @@ typedef class nsHTMLTextFieldAccessible nsHTMLTextFieldAccessibleWrap;
typedef class nsHTMLLinkAccessible nsHTMLLinkAccessibleWrap;
typedef class nsHTMLTableCellAccessible nsHTMLTableCellAccessibleWrap;
typedef class nsHTMLTableAccessible nsHTMLTableAccessibleWrap;
typedef class nsXULProgressMeterAccessible nsXULProgressMeterAccessibleWrap;
typedef class nsXULTextFieldAccessible nsXULTextFieldAccessibleWrap;
#endif

View File

@ -285,7 +285,7 @@ STDMETHODIMP nsAccessibleWrap::get_accValue(
GetXPAccessibleFor(varChild, getter_AddRefs(xpAccessible));
if (xpAccessible) {
nsAutoString value;
if (NS_FAILED(xpAccessible->GetFinalValue(value)))
if (NS_FAILED(xpAccessible->GetValue(value)))
return S_FALSE;
*pszValue = ::SysAllocString(value.get());

View File

@ -200,7 +200,6 @@ typedef class nsHTMLTextFieldAccessible nsHTMLTextFieldAccessibleWrap;
typedef class nsHTMLLinkAccessible nsHTMLLinkAccessibleWrap;
typedef class nsHTMLTableCellAccessible nsHTMLTableCellAccessibleWrap;
typedef class nsHTMLTableAccessible nsHTMLTableAccessibleWrap;
typedef class nsXULProgressMeterAccessible nsXULProgressMeterAccessibleWrap;
typedef class nsXULTextFieldAccessible nsXULTextFieldAccessibleWrap;
#endif

View File

@ -58,7 +58,6 @@ typedef class nsHTMLTextFieldAccessible nsHTMLTextFieldAccessibleWrap;
typedef class nsHTMLLinkAccessible nsHTMLLinkAccessibleWrap;
typedef class nsHTMLTableCellAccessible nsHTMLTableCellAccessibleWrap;
typedef class nsHTMLTableAccessible nsHTMLTableAccessibleWrap;
typedef class nsXULProgressMeterAccessible nsXULProgressMeterAccessibleWrap;
typedef class nsXULTextFieldAccessible nsXULTextFieldAccessibleWrap;
#endif

View File

@ -425,7 +425,7 @@ NS_IMETHODIMP nsXULGroupboxAccessible::GetName(nsAString& aName)
/**
* progressmeter
*/
NS_IMPL_ISUPPORTS_INHERITED0(nsXULProgressMeterAccessible, nsFormControlAccessible)
NS_IMPL_ISUPPORTS_INHERITED1(nsXULProgressMeterAccessible, nsFormControlAccessible, nsIAccessibleValue)
nsXULProgressMeterAccessible::nsXULProgressMeterAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell):
nsFormControlAccessible(aNode, aShell)
@ -438,26 +438,61 @@ NS_IMETHODIMP nsXULProgressMeterAccessible::GetRole(PRUint32 *_retval)
return NS_OK;
}
/**
* No states supported for progressmeter
*/
NS_IMETHODIMP nsXULProgressMeterAccessible::GetState(PRUint32 *aState)
{
nsresult rv = nsAccessible::GetState(aState);
*aState &= ~STATE_FOCUSABLE;
*aState &= ~STATE_FOCUSABLE; // Progress meters are not focusable
return rv;
}
NS_IMETHODIMP nsXULProgressMeterAccessible::GetValue(nsAString& _retval)
NS_IMETHODIMP nsXULProgressMeterAccessible::GetValue(nsAString& aValue)
{
aValue.Truncate();
nsAccessible::GetValue(aValue);
if (!aValue.IsEmpty()) {
return NS_OK;
}
nsCOMPtr<nsIDOMElement> element(do_QueryInterface(mDOMNode));
NS_ASSERTION(element, "No element for DOM node!");
element->GetAttribute(NS_LITERAL_STRING("value"), _retval);
if (!_retval.IsEmpty() && _retval.Last() != '%')
_retval.AppendLiteral("%");
element->GetAttribute(NS_LITERAL_STRING("value"), aValue);
if (!aValue.IsEmpty() && aValue.Last() != '%')
aValue.AppendLiteral("%");
return NS_OK;
}
NS_IMETHODIMP nsXULProgressMeterAccessible::GetMaximumValue(double *aMaximumValue)
{
*aMaximumValue = 1; // 100% = 1;
return NS_OK;
}
NS_IMETHODIMP nsXULProgressMeterAccessible::GetMinimumValue(double *aMinimumValue)
{
*aMinimumValue = 0;
return NS_OK;
}
NS_IMETHODIMP nsXULProgressMeterAccessible::GetMinimumIncrement(double *aMinimumIncrement)
{
*aMinimumIncrement = 0;
return NS_OK;
}
NS_IMETHODIMP nsXULProgressMeterAccessible::GetCurrentValue(double *aCurrentValue)
{
nsAutoString currentValue;
GetValue(currentValue);
PRInt32 error;
*aCurrentValue = currentValue.ToFloat(&error) / 100;
return NS_OK;
}
NS_IMETHODIMP nsXULProgressMeterAccessible::SetCurrentValue(double aValue)
{
return NS_ERROR_FAILURE; // Progress meters are readonly!
}
/**
* XUL Radio Button
*/

View File

@ -95,12 +95,13 @@ public:
class nsXULProgressMeterAccessible : public nsFormControlAccessible
{
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIACCESSIBLEVALUE
public:
nsXULProgressMeterAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell);
NS_IMETHOD GetRole(PRUint32 *_retval);
NS_IMETHOD GetState(PRUint32 *_retval);
NS_IMETHOD GetValue(nsAString &_retval);
NS_IMETHOD GetRole(PRUint32 *aRole);
NS_IMETHOD GetState(PRUint32 *aState);
NS_IMETHOD GetValue(nsAString &aValue);
};
class nsXULRadioButtonAccessible : public nsRadioButtonAccessible