Bug 350186. Accessible objects for xforms input controls. Patch by surkov. r=aaronlev, r=aaronr, sr=neil

This commit is contained in:
aaronleventhal%moonset.net 2006-09-25 15:22:05 +00:00
parent 81ff8fc99a
commit cbd3fb6983
12 changed files with 302 additions and 10 deletions

View File

@ -45,7 +45,7 @@
object. For that XBL binding of element should implement the interface.
*/
[scriptable, uuid(b3114d71-c7b2-4966-b1c9-dc66220430ac)]
[scriptable, uuid(1a57d854-12df-4b7b-8552-a3cd1fa90618)]
interface nsIAccessibleProvider : nsISupports
{
/**
@ -114,6 +114,12 @@ interface nsIAccessibleProvider : nsISupports
const long XFormsOuput = 0x00002002;
/** Used for trigger and submit elements */
const long XFormsTrigger = 0x00002003;
/** Used for input and textarea elements */
const long XFormsInput = 0x00002004;
/** Used for input[xsd:boolean] element */
const long XFormsInputBoolean = 0x00002005;
/** Used for secret element */
const long XFormsSecret = 0x00002006;
/** Used for range element */
const long XFormsRange = 0x00002007;

View File

@ -122,6 +122,7 @@ ACCESSIBILITY_ATOM(td, "td")
ACCESSIBILITY_ATOM(th, "th")
ACCESSIBILITY_ATOM(tfoot, "tfoot")
ACCESSIBILITY_ATOM(thead, "thead")
ACCESSIBILITY_ATOM(textarea, "textarea") // XForms
ACCESSIBILITY_ATOM(textbox, "textbox") // XUL
ACCESSIBILITY_ATOM(toolbaritem, "toolbaritem") // XUL
ACCESSIBILITY_ATOM(tr, "tr")

View File

@ -1443,6 +1443,15 @@ nsresult nsAccessibilityService::GetAccessibleByType(nsIDOMNode *aNode,
case nsIAccessibleProvider::XFormsTrigger:
*aAccessible = new nsXFormsTriggerAccessible(aNode, weakShell);
break;
case nsIAccessibleProvider::XFormsInput:
*aAccessible = new nsXFormsInputAccessible(aNode, weakShell);
break;
case nsIAccessibleProvider::XFormsInputBoolean:
*aAccessible = new nsXFormsInputBooleanAccessible(aNode, weakShell);
break;
case nsIAccessibleProvider::XFormsSecret:
*aAccessible = new nsXFormsSecretAccessible(aNode, weakShell);
break;
case nsIAccessibleProvider::XFormsRange:
*aAccessible = new nsXFormsRangeAccessible(aNode, weakShell);
break;

View File

@ -70,6 +70,9 @@ public:
NS_IMETHOD GetAllowsAnonChildAccessibles(PRBool *aAllowsAnonChildren);
protected:
// Used in GetActionName() methods.
enum { eAction_Click = 0 };
// Returns value of first child xforms element by tagname that is bound to
// instance node.
nsresult GetBoundChildElementValue(const nsAString& aTagName,

View File

@ -143,6 +143,184 @@ nsXFormsTriggerAccessible::DoAction(PRUint8 aIndex)
return NS_ERROR_INVALID_ARG;
}
// nsXFormsInputAccessible
nsXFormsInputAccessible::
nsXFormsInputAccessible(nsIDOMNode *aNode, nsIWeakReference *aShell):
nsXFormsAccessible(aNode, aShell)
{
}
NS_IMETHODIMP
nsXFormsInputAccessible::GetRole(PRUint32 *aRole)
{
NS_ENSURE_ARG_POINTER(aRole);
*aRole = ROLE_ENTRY;
return NS_OK;
}
NS_IMETHODIMP
nsXFormsInputAccessible::GetExtState(PRUint32 *aExtState)
{
NS_ENSURE_ARG_POINTER(aExtState);
*aExtState = 0;
NS_ENSURE_TRUE(mDOMNode, NS_ERROR_FAILURE);
nsresult rv = nsXFormsAccessible::GetExtState(aExtState);
NS_ENSURE_SUCCESS(rv, rv);
PRBool state = PR_FALSE;
rv = sXFormsService->IsReadonly(mDOMNode, &state);
NS_ENSURE_SUCCESS(rv, rv);
if (!state) {
rv = sXFormsService->IsRelevant(mDOMNode, &state);
NS_ENSURE_SUCCESS(rv, rv);
if (state) {
*aExtState |= EXT_STATE_EDITABLE | EXT_STATE_SELECTABLE_TEXT;
}
}
nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
if (content->NodeInfo()->Equals(nsAccessibilityAtoms::textarea))
*aExtState |= EXT_STATE_MULTI_LINE;
else
*aExtState |= EXT_STATE_SINGLE_LINE;
}
NS_IMETHODIMP
nsXFormsInputAccessible::GetNumActions(PRUint8* aCount)
{
NS_ENSURE_ARG_POINTER(aCount);
*aCount = 1;
return NS_OK;
}
NS_IMETHODIMP
nsXFormsInputAccessible::GetActionName(PRUint8 aIndex, nsAString& aName)
{
if (aIndex != eAction_Click)
return NS_ERROR_INVALID_ARG;
nsAccessible::GetTranslatedString(NS_LITERAL_STRING("activate"), aName);
return NS_OK;
}
NS_IMETHODIMP
nsXFormsInputAccessible::DoAction(PRUint8 aIndex)
{
if (aIndex != eAction_Click)
return NS_ERROR_INVALID_ARG;
return sXFormsService->Focus(mDOMNode);
}
// nsXFormsInputBooleanAccessible
nsXFormsInputBooleanAccessible::
nsXFormsInputBooleanAccessible(nsIDOMNode *aNode, nsIWeakReference *aShell):
nsXFormsAccessible(aNode, aShell)
{
}
NS_IMETHODIMP
nsXFormsInputBooleanAccessible::GetRole(PRUint32 *aRole)
{
NS_ENSURE_ARG_POINTER(aRole);
*aRole = ROLE_CHECKBUTTON;
return NS_OK;
}
NS_IMETHODIMP
nsXFormsInputBooleanAccessible::GetState(PRUint32 *aState)
{
nsresult rv = nsXFormsAccessible::GetState(aState);
NS_ENSURE_SUCCESS(rv, rv);
nsAutoString value;
rv = sXFormsService->GetValue(mDOMNode, value);
NS_ENSURE_SUCCESS(rv, rv);
if (value.EqualsLiteral("true"))
*aState |= STATE_CHECKED;
return NS_OK;
}
NS_IMETHODIMP
nsXFormsInputBooleanAccessible::GetNumActions(PRUint8 *aCount)
{
NS_ENSURE_ARG_POINTER(aCount);
*aCount = 1;
return NS_OK;
}
NS_IMETHODIMP
nsXFormsInputBooleanAccessible::GetActionName(PRUint8 aIndex, nsAString& aName)
{
if (aIndex != eAction_Click)
return NS_ERROR_INVALID_ARG;
nsAutoString value;
nsresult rv = sXFormsService->GetValue(mDOMNode, value);
NS_ENSURE_SUCCESS(rv, rv);
if (value.EqualsLiteral("true"))
nsAccessible::GetTranslatedString(NS_LITERAL_STRING("uncheck"), aName);
else
nsAccessible::GetTranslatedString(NS_LITERAL_STRING("check"), aName);
return NS_OK;
}
NS_IMETHODIMP
nsXFormsInputBooleanAccessible::DoAction(PRUint8 aIndex)
{
if (aIndex != eAction_Click)
return NS_ERROR_INVALID_ARG;
return DoCommand();
}
// nsXFormsSecretAccessible
nsXFormsSecretAccessible::
nsXFormsSecretAccessible(nsIDOMNode *aNode, nsIWeakReference *aShell):
nsXFormsInputAccessible(aNode, aShell)
{
}
NS_IMETHODIMP
nsXFormsSecretAccessible::GetRole(PRUint32 *aRole)
{
NS_ENSURE_ARG_POINTER(aRole);
*aRole = ROLE_PASSWORD_TEXT;
return NS_OK;
}
NS_IMETHODIMP
nsXFormsSecretAccessible::GetState(PRUint32 *aState)
{
nsresult rv = nsXFormsInputAccessible::GetState(aState);
NS_ENSURE_SUCCESS(rv, rv);
*aState |= STATE_PROTECTED;
return NS_OK;
}
NS_IMETHODIMP
nsXFormsSecretAccessible::GetValue(nsAString& aValue)
{
return NS_ERROR_FAILURE;
}
// nsXFormsRangeAccessible
nsXFormsRangeAccessible::

View File

@ -74,8 +74,6 @@ public:
class nsXFormsTriggerAccessible : public nsXFormsAccessible
{
public:
enum { eAction_Click = 0 };
nsXFormsTriggerAccessible(nsIDOMNode *aNode, nsIWeakReference *aShell);
NS_IMETHOD GetRole(PRUint32 *aRole);
@ -86,6 +84,56 @@ public:
NS_IMETHOD DoAction(PRUint8 aIndex);
};
/**
* Accessible object for xforms:input and xforms:textarea.
*
* XXX: nsXFormsInputAccessible should implement nsIAccessibleEditableText
* interface.
*/
class nsXFormsInputAccessible : public nsXFormsAccessible
{
public:
nsXFormsInputAccessible(nsIDOMNode *aNode, nsIWeakReference *aShell);
NS_IMETHOD GetRole(PRUint32 *aRole);
NS_IMETHOD GetExtState(PRUint32 *aState);
NS_IMETHOD GetNumActions(PRUint8 *aCount);
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
NS_IMETHOD DoAction(PRUint8 aIndex);
};
/**
* Accessible object for xforms:input[type="xsd:boolean"].
*/
class nsXFormsInputBooleanAccessible : public nsXFormsAccessible
{
public:
nsXFormsInputBooleanAccessible(nsIDOMNode *aNode, nsIWeakReference *aShell);
NS_IMETHOD GetRole(PRUint32 *aRole);
NS_IMETHOD GetState(PRUint32 *aState);
NS_IMETHOD GetNumActions(PRUint8 *aCount);
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
NS_IMETHOD DoAction(PRUint8 aIndex);
};
/**
* Accessible object for xforms:secret.
*/
class nsXFormsSecretAccessible : public nsXFormsInputAccessible
{
public:
nsXFormsSecretAccessible(nsIDOMNode *aNode, nsIWeakReference *aShell);
NS_IMETHOD GetRole(PRUint32 *aRole);
NS_IMETHOD GetState(PRUint32 *aState);
NS_IMETHOD GetValue(nsAString& aValue);
};
/**
* Accessible object for xforms:range.
*/

View File

@ -48,10 +48,10 @@
#endif
/* nsIXFormsUtilityService */
#define NS_IXFORMSUTILITYSERVICE_IID_STR "975fb01f-27a7-4dd2-a598-d00109538594"
#define NS_IXFORMSUTILITYSERVICE_IID_STR "aad08d14-dff8-4acb-bcd0-b6376295c82f"
#define NS_IXFORMSUTILITYSERVICE_IID \
{ 0x975fb01f, 0x27a7, 0x4dd2, \
{ 0xa5, 0x98, 0xd0, 0x1, 0x9, 0x53, 0x85, 0x94 } }
{ 0xaad08d14, 0xdff8, 0x4acb, \
{ 0xbc, 0xd0, 0xb6, 0x37, 0x62, 0x95, 0xc8, 0x2f } }
/**
* Private interface implemented by the nsXFormsUtilityService in XForms
@ -101,6 +101,11 @@ public:
*/
NS_IMETHOD GetValue(nsIDOMNode *aElement, nsAString& aValue) = 0;
/**
* Set the focus to xforms element.
*/
NS_IMETHOD Focus(nsIDOMNode *aElement) = 0;
/**
* Return @start attribute value of xforms:range element. Failure if
* given element is not xforms:range.

View File

@ -43,6 +43,7 @@
#include "nsIXFormsAccessors.h"
#include "nsIXFormsRangeConditionAccessors.h"
#include "nsIXFormsRangeAccessors.h"
#include "nsIXFormsUIWidget.h"
#include "nsXFormsUtils.h"
NS_IMPL_ISUPPORTS1(nsXFormsUtilityService, nsIXFormsUtilityService)
@ -55,6 +56,11 @@ nsCOMPtr<nsIXFormsAccessors> accessors;\
delegate->GetXFormsAccessors(getter_AddRefs(accessors));\
NS_ENSURE_TRUE(accessors, NS_ERROR_FAILURE);
#define GET_XFORMS_UIWIDGET \
NS_ENSURE_ARG_POINTER(aElement);\
nsCOMPtr<nsIXFormsUIWidget> widget(do_QueryInterface(aElement));\
NS_ENSURE_TRUE(widget, NS_ERROR_FAILURE);\
NS_IMETHODIMP
nsXFormsUtilityService::IsReadonly(nsIDOMNode *aElement, PRBool *aState)
{
@ -118,8 +124,16 @@ nsXFormsUtilityService::IsInRange(nsIDOMNode *aElement, PRUint32 *aState)
NS_IMETHODIMP
nsXFormsUtilityService::GetValue(nsIDOMNode *aElement, nsAString& aValue)
{
GET_XFORMS_ACCESSORS
return accessors->GetValue(aValue);
GET_XFORMS_UIWIDGET
return widget->GetCurrentValue(aValue);
}
NS_IMETHODIMP
nsXFormsUtilityService::Focus(nsIDOMNode *aElement)
{
GET_XFORMS_UIWIDGET
PRBool advanced = PR_FALSE;
return widget->Focus(&advanced);
}
NS_IMETHODIMP

View File

@ -57,6 +57,7 @@ public:
NS_IMETHOD IsValid(nsIDOMNode *aElement, PRBool *aState);
NS_IMETHOD IsInRange(nsIDOMNode *aElement, PRUint32 *aState);
NS_IMETHOD GetValue(nsIDOMNode *aElement, nsAString& aValue);
NS_IMETHOD Focus(nsIDOMNode *aElement);
NS_IMETHOD GetRangeStart(nsIDOMNode *aElement, nsAString& aValue);
NS_IMETHOD GetRangeEnd(nsIDOMNode *aElement, nsAString& aValue);

View File

@ -627,6 +627,14 @@
<html:input anonid="control" xbl:inherits="accesskey" type="password"/>
<children/>
</content>
<implementation implements="nsIAccessibleProvider">
<property name="accessibleType" readonly="true">
<getter>
return Components.interfaces.nsIAccessibleProvider.XFormsSecret;
</getter>
</property>
</implementation>
</binding>

View File

@ -496,6 +496,14 @@
<children/>
</content>
<implementation implements="nsIAccessibleProvider">
<property name="accessibleType" readonly="true">
<getter>
return Components.interfaces.nsIAccessibleProvider.XFormsSecret;
</getter>
</property>
</implementation>
<handlers>
<handler event="keypress" keycode="VK_RETURN">
if (event.originalTarget == this.control) {

View File

@ -65,7 +65,12 @@
<binding id="xformswidget-input-base"
extends="chrome://xforms/content/xforms.xml#xformswidget-base">
<implementation implements="nsIXFormsUIWidget">
<implementation implements="nsIXFormsUIWidget, nsIAccessibleProvider">
<property name="accessibleType" readonly="true">
<getter>
return Components.interfaces.nsIAccessibleProvider.XFormsInput;
</getter>
</property>
<method name="refresh">
<body>
@ -119,7 +124,13 @@
<binding id="xformswidget-input-boolean-base"
extends="chrome://xforms/content/xforms.xml#xformswidget-base">
<implementation>
<implementation implements="nsIAccessibleProvider">
<property name="accessibleType" readonly="true">
<getter>
return Components.interfaces.nsIAccessibleProvider.XFormsInputBoolean;
</getter>
</property>
<method name="refresh">
<body>
this.changed = false;