diff --git a/accessible/macbuild/accessibleIDL.xml b/accessible/macbuild/accessibleIDL.xml
index 6ddcf5872a26..9b6d5ac26ca9 100644
--- a/accessible/macbuild/accessibleIDL.xml
+++ b/accessible/macbuild/accessibleIDL.xml
@@ -780,13 +780,6 @@
Text
-
- Name
- nsIAccessibleSelection.idl
- MacOS
- Text
-
-
Name
nsIAccessibleValue.idl
@@ -867,11 +860,6 @@
nsIAccessibleAction.idl
MacOS
-
- Name
- nsIAccessibleSelection.idl
- MacOS
-
Name
nsIAccessibleValue.idl
@@ -1631,13 +1619,6 @@
Text
-
- Name
- nsIAccessibleSelection.idl
- MacOS
- Text
-
-
Name
nsIAccessibleValue.idl
@@ -1718,11 +1699,6 @@
nsIAccessibleAction.idl
MacOS
-
- Name
- nsIAccessibleSelection.idl
- MacOS
-
Name
nsIAccessibleValue.idl
@@ -1813,12 +1789,6 @@
nsIAccessibleAction.idl
MacOS
-
- headers
- Name
- nsIAccessibleSelection.idl
- MacOS
-
headers
Name
diff --git a/accessible/public/Makefile.in b/accessible/public/Makefile.in
index 99aa95c5a719..f4954c671857 100644
--- a/accessible/public/Makefile.in
+++ b/accessible/public/Makefile.in
@@ -41,7 +41,6 @@ XPIDLSRCS = \
nsIAccessibleHyperText.idl \
nsIAccessibleProvider.idl \
nsIAccessibleSelectable.idl \
- nsIAccessibleSelection.idl \
nsIAccessibleTable.idl \
nsIAccessibleText.idl \
nsIAccessibleValue.idl \
diff --git a/accessible/public/makefile.win b/accessible/public/makefile.win
index 713ed534bb00..d51316a4c7d8 100644
--- a/accessible/public/makefile.win
+++ b/accessible/public/makefile.win
@@ -35,7 +35,6 @@ XPIDLSRCS = \
.\nsIAccessibleHyperText.idl \
.\nsIAccessibleProvider.idl \
.\nsIAccessibleSelectable.idl \
- .\nsIAccessibleSelection.idl \
.\nsIAccessibleTable.idl \
.\nsIAccessibleText.idl \
.\nsIAccessibleValue.idl \
diff --git a/accessible/public/nsIAccessibleSelectable.idl b/accessible/public/nsIAccessibleSelectable.idl
index 45908df85c4c..f1cbbc6bfe08 100644
--- a/accessible/public/nsIAccessibleSelectable.idl
+++ b/accessible/public/nsIAccessibleSelectable.idl
@@ -21,7 +21,11 @@
*
* Contributor(s):
* John Gaunt
- */
+ * Marc Mulcahy (marc.mulcahy@sun.com)
+ * Paul Sandoz (paul.sandoz@sun.com)
+ * Bill Haneman (bill.haneman@sun.com)
+ * Kyle Yuan (kyle.yuan@sun.com)
+*/
#include "nsISupports.idl"
#include "nsIAccessible.idl"
@@ -30,5 +34,43 @@
[scriptable, uuid(34d268d6-1dd2-11b2-9d63-83a5e0ada290)]
interface nsIAccessibleSelectable : nsISupports
{
- nsISupportsArray GetSelectedChildren();
+ nsISupportsArray GetSelectedChildren();
+
+ /**
+ * Returns the number of accessible children currently selected.
+ */
+ readonly attribute long selectionCount;
+
+ /**
+ * Adds the specified accessible child of the object to the
+ * object's selection.
+ */
+ void addSelection(in long index);
+
+ /**
+ * Removes the specified child of the object from the object's selection.
+ */
+ void removeSelection(in long index);
+
+ /**
+ * Clears the selection in the object so that no children in the object
+ * are selected.
+ */
+ void clearSelection();
+
+ /**
+ * Returns a reference to the accessible object representing the specified
+ * selected child of the object.
+ */
+ nsIAccessible refSelection(in long index);
+
+ /**
+ * Determines if the current child of this object is selected
+ */
+ boolean isChildSelected(in long index);
+
+ /**
+ * If the object does not accept multiple selection, return false.
+ */
+ boolean selectAllSelection();
};
diff --git a/accessible/src/base/nsSelectAccessible.cpp b/accessible/src/base/nsSelectAccessible.cpp
index beef5559ad4d..86c31f2d0fa6 100644
--- a/accessible/src/base/nsSelectAccessible.cpp
+++ b/accessible/src/base/nsSelectAccessible.cpp
@@ -22,7 +22,7 @@
* Contributor(s):
* Original Author: Eric Vaughan (evaughan@netscape.com)
* Contributor(s): John Gaunt (jgaunt@netscape.com)
- *
+ * Kyle Yuan (kyle.yuan@sun.com)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@@ -42,19 +42,20 @@
#include "nsFormControlAccessible.h"
#include "nsIAtom.h"
#include "nsIComboboxControlFrame.h"
-#include "nsIDOMEventReceiver.h"
-#include "nsIDOMHTMLCollection.h"
-#include "nsIDOMHTMLOptionElement.h"
#include "nsIDOMHTMLOptGroupElement.h"
-#include "nsIDOMText.h"
#include "nsIDOMHTMLSelectElement.h"
+#include "nsIDOMText.h"
+#include "nsIDOMXULMultSelectCntrlEl.h"
+#include "nsIDOMXULSelectCntrlEl.h"
+#include "nsIDOMXULSelectCntrlItemEl.h"
#include "nsIFrame.h"
#include "nsIListControlFrame.h"
#include "nsISelectControlFrame.h"
+#include "nsIServiceManager.h"
#include "nsLayoutAtoms.h"
#include "nsRootAccessible.h"
#include "nsSelectAccessible.h"
-#include "nsIServiceManager.h"
+
/** ------------------------------------------------------ */
/** First, the common widgets */
@@ -196,206 +197,6 @@ NS_IMETHODIMP nsSelectOptionAccessible::GetAccName(nsAString& _retval)
return NS_ERROR_FAILURE;
}
-/** ------------------------------------------------------ */
-/** Secondly, the Listbox widget */
-/** ------------------------------------------------------ */
-
-/** ----- nsListboxAccessible ----- */
-
-/** Constructor */
-nsListboxAccessible::nsListboxAccessible(nsIDOMNode* aDOMNode,
- nsIWeakReference* aShell):
-nsAccessible(aDOMNode, aShell)
-{
-}
-
-NS_IMPL_ISUPPORTS_INHERITED1(nsListboxAccessible, nsAccessible, nsIAccessibleSelectable)
-
-/** We are a window, as far as MSAA is concerned */
-NS_IMETHODIMP nsListboxAccessible::GetAccRole(PRUint32 *_retval)
-{
- *_retval = ROLE_WINDOW;
- return NS_OK;
-}
-
-/**
- * We always have 1 child: a subclass of nsSelectListAccessible.
- */
-NS_IMETHODIMP nsListboxAccessible::GetAccChildCount(PRInt32 *_retval)
-{
- *_retval = 1;
- return NS_OK;
-}
-
-/**
- * As a nsHTMLListboxAccessible we can have the following states:
- * STATE_FOCUSED
- * STATE_READONLY
- * STATE_FOCUSABLE
- */
-NS_IMETHODIMP nsListboxAccessible::GetAccState(PRUint32 *_retval)
-{
- // Get focus status from base class
- nsAccessible::GetAccState(_retval);
-
- *_retval |= STATE_READONLY | STATE_FOCUSABLE;
-
- return NS_OK;
-}
-
-/**
- * No-op method body. subclasses MUST override this method
- */
-NS_IMETHODIMP nsListboxAccessible::GetSelectedChildren(nsISupportsArray **_retval)
-{
- *_retval = nsnull;
- return NS_OK;
-}
-
-/** ------------------------------------------------------ */
-/** Finally, the Combobox widgets */
-/** ------------------------------------------------------ */
-
-/** ----- nsComboboxAccessible ----- */
-
-/**
- * Constructor -- set initial state - closed, register ourself
- */
-nsComboboxAccessible::nsComboboxAccessible(nsIDOMNode* aDOMNode,
- nsIWeakReference* aShell):
-nsAccessible(aDOMNode, aShell)
-{
- mRegistered = PR_FALSE;
- mOpen = PR_FALSE;
- SetupMenuListener();
-}
-
-/**
- * Destructor -- If we are registered, remove ourselves as a listener.
- */
-nsComboboxAccessible::~nsComboboxAccessible()
-{
- if (mRegistered) {
- nsCOMPtr eventReceiver(do_QueryInterface(mDOMNode));
- if (eventReceiver)
- eventReceiver->RemoveEventListener(NS_LITERAL_STRING("popupshowing"), this, PR_TRUE);
- }
-}
-
-/**
- * Inherit the ISupports impl from nsAccessible,
- * handle nsIDOMXULListener and nsIAccessibleSelectable ourself
- */
-NS_IMPL_ISUPPORTS_INHERITED2(nsComboboxAccessible, nsAccessible, nsIDOMXULListener, nsIAccessibleSelectable)
-
-/**
- * If we aren't already registered, register ourselves as a
- * listener to "popupshowing" events on our DOM node. Set our
- * state to registered, but don't notify MSAA as they
- * don't need to know about this state.
- */
-void
-nsComboboxAccessible::SetupMenuListener()
-{
- // if not already registered as a popup listener, register ourself
- if (!mRegistered) {
- nsCOMPtr eventReceiver(do_QueryInterface(mDOMNode));
- if (eventReceiver && NS_SUCCEEDED(eventReceiver->AddEventListener(NS_LITERAL_STRING("popupshowing"), this, PR_TRUE)))
- mRegistered = PR_TRUE;
- }
-}
-
-/** We are a combobox */
-NS_IMETHODIMP nsComboboxAccessible::GetAccRole(PRUint32 *_retval)
-{
- *_retval = ROLE_COMBOBOX;
- return NS_OK;
-}
-
-/**
- * We always have 3 children: TextField, Button, Window. In that order
- */
-NS_IMETHODIMP nsComboboxAccessible::GetAccChildCount(PRInt32 *_retval)
-{
- *_retval = 3;
- return NS_OK;
-}
-
-/**
- * nsIAccessibleSelectable method. No-op because our selection is returned through
- * GetValue(). This _may_ change just to provide additional info for the vendors
- * and another option for them to get at stuff. Despite the fact that we are
- * single selection only.
- */
-NS_IMETHODIMP nsComboboxAccessible::GetSelectedChildren(nsISupportsArray **_retval)
-{
- *_retval = nsnull;
- return NS_OK;
-}
-
-/**
- * As a nsComboboxAccessible we can have the following states:
- * STATE_FOCUSED
- * STATE_READONLY
- * STATE_FOCUSABLE
- * STATE_HASPOPUP
- * STATE_EXPANDED
- * STATE_COLLAPSED
- */
-NS_IMETHODIMP nsComboboxAccessible::GetAccState(PRUint32 *_retval)
-{
- // Get focus status from base class
- nsAccessible::GetAccState(_retval);
-
- if (mOpen)
- *_retval |= STATE_EXPANDED;
- else
- *_retval |= STATE_COLLAPSED;
-
- *_retval |= STATE_HASPOPUP | STATE_READONLY | STATE_FOCUSABLE;
-
- return NS_OK;
-}
-
-/**
- * Set our state to open and (TBD) fire an event to MSAA saying our state
- * has changed.
- */
-NS_IMETHODIMP nsComboboxAccessible::PopupShowing(nsIDOMEvent* aEvent)
-{
- mOpen = PR_TRUE;
-
- /* TBD send state change event */
-
- return NS_OK;
-}
-
-/**
- * Set our state to not open and (TDB) fire an event to MSAA saying
- * our state has changed.
- */
-NS_IMETHODIMP nsComboboxAccessible::PopupHiding(nsIDOMEvent* aEvent)
-{
- mOpen = PR_FALSE;
-
- /* TBD send state change event */
-
- return NS_OK;
-}
-
-/**
- * Set our state to not open and (TDB) fire an event to MSAA saying
- * our state has changed.
- */
-NS_IMETHODIMP nsComboboxAccessible::Close(nsIDOMEvent* aEvent)
-{
- mOpen = PR_FALSE;
-
- /* TBD send state change event */
-
- return NS_OK;
-}
-
/** ----- nsComboboxTextFieldAccessible ----- */
/** Constructor */
diff --git a/accessible/src/base/nsSelectAccessible.h b/accessible/src/base/nsSelectAccessible.h
index d1494b10d00a..cb6f0f031d6c 100644
--- a/accessible/src/base/nsSelectAccessible.h
+++ b/accessible/src/base/nsSelectAccessible.h
@@ -22,7 +22,7 @@
* Contributor(s):
* Original Author: Eric Vaughan (evaughan@netscape.com)
* Contributor(s): John Gaunt (jgaunt@netscape.com)
- *
+ * Kyle Yuan (kyle.yuan@sun.com)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@@ -43,12 +43,15 @@
#include "nsBaseWidgetAccessible.h"
#include "nsIAccessibleSelectable.h"
+#include "nsIDOMEventReceiver.h"
#include "nsIDOMXULListener.h"
/** ------------------------------------------------------ */
/** First, the common widgets */
/** ------------------------------------------------------ */
+enum { eSelection_Add=0, eSelection_Remove=1, eSelection_GetState=2 };
+
/**
* The list that contains all the options in the select.
*/
@@ -91,76 +94,6 @@ protected:
nsCOMPtr mParent;
};
-/** ------------------------------------------------------ */
-/** Secondly, the Listbox widget */
-/** ------------------------------------------------------ */
-
-/**
- * A class that represents the Listbox widget.
- */
-class nsListboxAccessible : public nsAccessible,
- public nsIAccessibleSelectable
-{
-public:
-
- NS_DECL_ISUPPORTS_INHERITED
- NS_DECL_NSIACCESSIBLESELECTABLE
-
- nsListboxAccessible (nsIDOMNode* aDOMNode, nsIWeakReference* aShell);
- virtual ~nsListboxAccessible () {}
-
- /* ----- nsIAccessible ----- */
- NS_IMETHOD GetAccRole(PRUint32 *_retval);
- NS_IMETHOD GetAccChildCount(PRInt32 *_retval);
- NS_IMETHOD GetAccState(PRUint32 *_retval);
-
-};
-
-/** ------------------------------------------------------ */
-/** Finally, the Combobox widgets */
-/** ------------------------------------------------------ */
-
-/**
- * A class the represents the HTML Combobox widget.
- */
-class nsComboboxAccessible : public nsAccessible,
- public nsIAccessibleSelectable,
- public nsIDOMXULListener
-{
-public:
-
- NS_DECL_ISUPPORTS_INHERITED
- NS_DECL_NSIACCESSIBLESELECTABLE
-
- nsComboboxAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell);
- virtual ~nsComboboxAccessible();
-
- /* ----- nsIAccessible ----- */
- NS_IMETHOD GetAccRole(PRUint32 *_retval);
- NS_IMETHOD GetAccChildCount(PRInt32 *_retval);
- NS_IMETHOD GetAccState(PRUint32 *_retval);
-
- /* ----- nsIDOMXULListener ----- */
- NS_IMETHOD PopupShowing(nsIDOMEvent* aEvent);
- NS_IMETHOD PopupShown(nsIDOMEvent* aEvent) { return NS_OK; }
- NS_IMETHOD PopupHiding(nsIDOMEvent* aEvent);
- NS_IMETHOD PopupHidden(nsIDOMEvent* aEvent) { return NS_OK; }
-
- NS_IMETHOD Close(nsIDOMEvent* aEvent);
- NS_IMETHOD Command(nsIDOMEvent* aEvent) { return NS_OK; }
- NS_IMETHOD Broadcast(nsIDOMEvent* aEvent) { return NS_OK; }
- NS_IMETHOD CommandUpdate(nsIDOMEvent* aEvent) { return NS_OK; }
- NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent) { return NS_OK; }
-
- virtual void SetupMenuListener();
-
-protected:
-
- PRBool mRegistered;
- PRBool mOpen;
-
-};
-
/**
* A class the represents the text field in the Combobox to the left
* of the drop down button
diff --git a/accessible/src/html/nsHTMLSelectAccessible.cpp b/accessible/src/html/nsHTMLSelectAccessible.cpp
index 958ed5cacba9..7cb7be02ada0 100644
--- a/accessible/src/html/nsHTMLSelectAccessible.cpp
+++ b/accessible/src/html/nsHTMLSelectAccessible.cpp
@@ -21,7 +21,7 @@
*
* Contributor(s):
* Original Author: Eric Vaughan (evaughan@netscape.com)
- *
+ * Contributor(s): Kyle Yuan (kyle.yuan@sun.com)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@@ -80,6 +80,242 @@
* - nsHTMLSelectOptionAccessible
*/
+/** ------------------------------------------------------ */
+/** Impl. of nsHTMLSelectableAccessible */
+/** ------------------------------------------------------ */
+
+// Helper class
+nsHTMLSelectableAccessible::iterator::iterator(nsHTMLSelectableAccessible *aParent) : mParent(aParent)
+{
+ mLength = mIndex = 0;
+ mSelCount = 0;
+
+ nsCOMPtr htmlSelect(do_QueryInterface(mParent->mDOMNode));
+ if (htmlSelect) {
+ htmlSelect->GetOptions(getter_AddRefs(mOptions));
+ if (mOptions)
+ mOptions->GetLength(&mLength);
+ }
+}
+
+PRBool nsHTMLSelectableAccessible::iterator::Advance()
+{
+ if (mIndex < mLength) {
+ nsCOMPtr tempNode;
+ if (mOptions) {
+ mOptions->Item(mIndex, getter_AddRefs(tempNode));
+ mOption = do_QueryInterface(tempNode);
+ }
+ mIndex++;
+ return PR_TRUE;
+ }
+ return PR_FALSE;
+}
+
+void nsHTMLSelectableAccessible::iterator::CalcSelectionCount(PRInt32 *aSelectionCount)
+{
+ PRBool isSelected = PR_FALSE;
+
+ if (mOption)
+ mOption->GetSelected(&isSelected);
+
+ if (isSelected)
+ (*aSelectionCount)++;
+}
+
+void nsHTMLSelectableAccessible::iterator::AddAccessibleIfSelected(nsIAccessibilityService *aAccService,
+ nsISupportsArray *aSelectedAccessibles,
+ nsIPresContext *aContext)
+{
+ PRBool isSelected = PR_FALSE;
+ nsCOMPtr tempAccess;
+
+ if (mOption) {
+ mOption->GetSelected(&isSelected);
+ if (isSelected)
+ aAccService->CreateHTMLSelectOptionAccessible(mOption, mParent, aContext, getter_AddRefs(tempAccess));
+ }
+
+ if (tempAccess)
+ aSelectedAccessibles->AppendElement(tempAccess);
+}
+
+PRBool nsHTMLSelectableAccessible::iterator::GetAccessibleIfSelected(PRInt32 aIndex,
+ nsIAccessibilityService *aAccService,
+ nsIPresContext *aContext,
+ nsIAccessible **_retval)
+{
+ PRBool isSelected = PR_FALSE;
+ nsCOMPtr tempAccess;
+
+ *_retval = nsnull;
+
+ if (mOption) {
+ mOption->GetSelected(&isSelected);
+ if (isSelected) {
+ if (mSelCount == aIndex) {
+ aAccService->CreateHTMLSelectOptionAccessible(mOption, mParent, aContext, getter_AddRefs(tempAccess));
+ *_retval = tempAccess;
+ NS_IF_ADDREF(*_retval);
+ return PR_TRUE;
+ }
+ mSelCount++;
+ }
+ }
+
+ return PR_FALSE;
+}
+
+void nsHTMLSelectableAccessible::iterator::Select(PRBool aSelect)
+{
+ if (mOption)
+ mOption->SetSelected(aSelect);
+}
+
+nsHTMLSelectableAccessible::nsHTMLSelectableAccessible(nsIDOMNode* aDOMNode,
+ nsIWeakReference* aShell):
+nsAccessible(aDOMNode, aShell)
+{
+}
+
+NS_IMPL_ISUPPORTS_INHERITED1(nsHTMLSelectableAccessible, nsAccessible, nsIAccessibleSelectable)
+
+// Helper methods
+NS_IMETHODIMP nsHTMLSelectableAccessible::ChangeSelection(PRInt32 aIndex, PRUint8 aMethod, PRBool *aSelState)
+{
+ *aSelState = PR_FALSE;
+
+ nsCOMPtr htmlSelect(do_QueryInterface(mDOMNode));
+ if (!htmlSelect)
+ return NS_ERROR_FAILURE;
+
+ nsCOMPtr options;
+ htmlSelect->GetOptions(getter_AddRefs(options));
+ if (!options)
+ return NS_ERROR_FAILURE;
+
+ nsCOMPtr tempNode;
+ options->Item(aIndex, getter_AddRefs(tempNode));
+ nsCOMPtr tempOption(do_QueryInterface(tempNode));
+ if (!tempOption)
+ return NS_ERROR_FAILURE;
+
+ tempOption->GetSelected(aSelState);
+ if (eSelection_Add == aMethod && !(*aSelState))
+ tempOption->SetSelected(PR_TRUE);
+ else if (eSelection_Remove == aMethod && (*aSelState))
+ tempOption->SetSelected(PR_FALSE);
+ return NS_OK;
+}
+
+// Interface methods
+NS_IMETHODIMP nsHTMLSelectableAccessible::GetSelectedChildren(nsISupportsArray **_retval)
+{
+ *_retval = nsnull;
+
+ nsCOMPtr accService(do_GetService("@mozilla.org/accessibilityService;1"));
+ if (!accService)
+ return NS_ERROR_FAILURE;
+
+ nsCOMPtr selectedAccessibles;
+ NS_NewISupportsArray(getter_AddRefs(selectedAccessibles));
+ if (!selectedAccessibles)
+ return NS_ERROR_OUT_OF_MEMORY;
+
+ nsCOMPtr context;
+ GetPresContext(context);
+ if (!context)
+ return NS_ERROR_FAILURE;
+
+ nsHTMLSelectableAccessible::iterator iter(this);
+ while (iter.Advance())
+ iter.AddAccessibleIfSelected(accService, selectedAccessibles, context);
+
+ PRUint32 uLength = 0;
+ selectedAccessibles->Count(&uLength);
+ if (uLength != 0) { // length of nsISupportsArray containing selected options
+ *_retval = selectedAccessibles;
+ NS_ADDREF(*_retval);
+ }
+ return NS_OK;
+}
+
+// return the nth selected child's nsIAccessible object
+NS_IMETHODIMP nsHTMLSelectableAccessible::RefSelection(PRInt32 aIndex, nsIAccessible **_retval)
+{
+ *_retval = nsnull;
+
+ nsCOMPtr accService(do_GetService("@mozilla.org/accessibilityService;1"));
+ if (!accService)
+ return NS_ERROR_FAILURE;
+
+ nsCOMPtr context;
+ GetPresContext(context);
+ if (!context)
+ return NS_ERROR_FAILURE;
+
+ nsHTMLSelectableAccessible::iterator iter(this);
+ while (iter.Advance())
+ if (iter.GetAccessibleIfSelected(aIndex, accService, context, _retval))
+ return NS_OK;
+
+ // No matched item found
+ return NS_ERROR_FAILURE;
+}
+
+NS_IMETHODIMP nsHTMLSelectableAccessible::GetSelectionCount(PRInt32 *aSelectionCount)
+{
+ *aSelectionCount = 0;
+
+ nsHTMLSelectableAccessible::iterator iter(this);
+ while (iter.Advance())
+ iter.CalcSelectionCount(aSelectionCount);
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsHTMLSelectableAccessible::AddSelection(PRInt32 aIndex)
+{
+ PRBool isSelected;
+ return ChangeSelection(aIndex, eSelection_Add, &isSelected);
+}
+
+NS_IMETHODIMP nsHTMLSelectableAccessible::RemoveSelection(PRInt32 aIndex)
+{
+ PRBool isSelected;
+ return ChangeSelection(aIndex, eSelection_Remove, &isSelected);
+}
+
+NS_IMETHODIMP nsHTMLSelectableAccessible::IsChildSelected(PRInt32 aIndex, PRBool *_retval)
+{
+ *_retval = PR_FALSE;
+ return ChangeSelection(aIndex, eSelection_GetState, _retval);
+}
+
+NS_IMETHODIMP nsHTMLSelectableAccessible::ClearSelection()
+{
+ nsHTMLSelectableAccessible::iterator iter(this);
+ while (iter.Advance())
+ iter.Select(PR_FALSE);
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsHTMLSelectableAccessible::SelectAllSelection(PRBool *_retval)
+{
+ *_retval = PR_FALSE;
+
+ nsCOMPtr htmlSelect(do_QueryInterface(mDOMNode));
+ if (!htmlSelect)
+ return NS_ERROR_FAILURE;
+
+ htmlSelect->GetMultiple(_retval);
+ if (*_retval) {
+ nsHTMLSelectableAccessible::iterator iter(this);
+ while (iter.Advance())
+ iter.Select(PR_TRUE);
+ }
+ return NS_OK;
+}
+
/** ------------------------------------------------------ */
/** First, the common widgets */
/** ------------------------------------------------------ */
@@ -478,8 +714,6 @@ NS_IMETHODIMP nsHTMLSelectOptGroupAccessible::GetAccNumActions(PRUint8 *_retval)
return NS_ERROR_NOT_IMPLEMENTED;
}
-
-
/** ------------------------------------------------------ */
/** Secondly, the Listbox widget */
/** ------------------------------------------------------ */
@@ -488,10 +722,42 @@ NS_IMETHODIMP nsHTMLSelectOptGroupAccessible::GetAccNumActions(PRUint8 *_retval)
/** Constructor */
nsHTMLListboxAccessible::nsHTMLListboxAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell):
-nsListboxAccessible(aDOMNode, aShell)
+nsHTMLSelectableAccessible(aDOMNode, aShell)
{
}
+/** We are a window, as far as MSAA is concerned */
+NS_IMETHODIMP nsHTMLListboxAccessible::GetAccRole(PRUint32 *_retval)
+{
+ *_retval = ROLE_WINDOW;
+ return NS_OK;
+}
+
+/**
+ * We always have 1 child: a subclass of nsSelectListAccessible.
+ */
+NS_IMETHODIMP nsHTMLListboxAccessible::GetAccChildCount(PRInt32 *_retval)
+{
+ *_retval = 1;
+ return NS_OK;
+}
+
+/**
+ * As a nsHTMLListboxAccessible we can have the following states:
+ * STATE_FOCUSED
+ * STATE_READONLY
+ * STATE_FOCUSABLE
+ */
+NS_IMETHODIMP nsHTMLListboxAccessible::GetAccState(PRUint32 *_retval)
+{
+ // Get focus status from base class
+ nsAccessible::GetAccState(_retval);
+
+ *_retval |= STATE_READONLY | STATE_FOCUSABLE;
+
+ return NS_OK;
+}
+
/**
* Our last (and only) child is an nsHTMLSelectListAccessible object
*/
@@ -530,79 +796,59 @@ NS_IMETHODIMP nsHTMLListboxAccessible::GetAccValue(nsAString& _retval)
return NS_ERROR_FAILURE;
}
-/**
- * nsIAccessibleSelectable method.
- * - gets from the Select DOMNode the list of all Select Options
- * - iterates through all of the options looking for selected Options
- * - creates IAccessible objects for selected Options
- * - Returns the IAccessibles for selectd Options in the nsISupportsArray
- *
- * retval will be nsnull if:
- * - there are no Options in the Select Element
- * - there are Options but none are selected
- * - the DOMNode is not a nsIDOMHTMLSelectElement ( shouldn't happen )
- */
-NS_IMETHODIMP nsHTMLListboxAccessible::GetSelectedChildren(nsISupportsArray **_retval)
-{
- nsCOMPtr select(do_QueryInterface(mDOMNode));
- if(select) {
- nsCOMPtr options;
- // get all the options in the select
- select->GetOptions(getter_AddRefs(options));
- if (options) {
- // set up variables we need to get the selected options and to get their nsIAccessile objects
- PRUint32 length;
- options->GetLength(&length);
- nsCOMPtr accService(do_GetService("@mozilla.org/accessibilityService;1"));
- nsCOMPtr selectedAccessibles;
- NS_NewISupportsArray(getter_AddRefs(selectedAccessibles));
- if (!selectedAccessibles || !accService)
- return NS_ERROR_FAILURE;
- // find the selected options and get the accessible objects;
- PRBool isSelected = PR_FALSE;
- nsCOMPtr context;
- GetPresContext(context);
- for (PRUint32 i = 0 ; i < length ; i++) {
- nsCOMPtr tempNode;
- options->Item(i,getter_AddRefs(tempNode));
- if (tempNode) {
- nsCOMPtr tempOption(do_QueryInterface(tempNode));
- if (tempOption)
- tempOption->GetSelected(&isSelected);
- if (isSelected) {
- nsCOMPtr tempAccess;
- accService->CreateHTMLSelectOptionAccessible(tempOption, this, context, getter_AddRefs(tempAccess));
- if ( tempAccess )
- selectedAccessibles->AppendElement(tempAccess);
- isSelected = PR_FALSE;
- }
- }
- }
- selectedAccessibles->Count(&length); // reusing length
- if ( length != 0 ) { // length of nsISupportsArray containing selected options
- *_retval = selectedAccessibles;
- NS_IF_ADDREF(*_retval);
- return NS_OK;
- }
- }
- }
- // no options, not a select or none of the options are selected
- *_retval = nsnull;
- return NS_OK;
-}
-
/** ------------------------------------------------------ */
/** Finally, the Combobox widgets */
/** ------------------------------------------------------ */
/** ----- nsHTMLComboboxAccessible ----- */
-/** Constructor */
nsHTMLComboboxAccessible::nsHTMLComboboxAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell):
-nsComboboxAccessible(aDOMNode, aShell)
+nsHTMLSelectableAccessible(aDOMNode, aShell)
{
}
+/** We are a combobox */
+NS_IMETHODIMP nsHTMLComboboxAccessible::GetAccRole(PRUint32 *_retval)
+{
+ *_retval = ROLE_COMBOBOX;
+ return NS_OK;
+}
+
+/**
+ * We always have 3 children: TextField, Button, Window. In that order
+ */
+NS_IMETHODIMP nsHTMLComboboxAccessible::GetAccChildCount(PRInt32 *_retval)
+{
+ *_retval = 3;
+ return NS_OK;
+}
+
+/**
+ * As a nsComboboxAccessible we can have the following states:
+ * STATE_FOCUSED
+ * STATE_READONLY
+ * STATE_FOCUSABLE
+ * STATE_HASPOPUP
+ * STATE_EXPANDED
+ * STATE_COLLAPSED
+ */
+NS_IMETHODIMP nsHTMLComboboxAccessible::GetAccState(PRUint32 *_retval)
+{
+ // Get focus status from base class
+ nsAccessible::GetAccState(_retval);
+
+ // we are open or closed
+ PRBool isOpen = PR_FALSE;
+ nsCOMPtr comboFrame(do_QueryInterface(GetBoundsFrame()));
+ if (comboFrame)
+ comboFrame->IsDroppedDown(&isOpen);
+
+ *_retval |= isOpen ? STATE_EXPANDED : STATE_COLLAPSED;
+ *_retval |= STATE_HASPOPUP | STATE_READONLY | STATE_FOCUSABLE;
+
+ return NS_OK;
+}
+
/**
* Our last child is an nsHTMLComboboxWindowAccessible object
*/
diff --git a/accessible/src/html/nsHTMLSelectAccessible.h b/accessible/src/html/nsHTMLSelectAccessible.h
index 4fcc2a0a0dfc..d416c4c999e2 100644
--- a/accessible/src/html/nsHTMLSelectAccessible.h
+++ b/accessible/src/html/nsHTMLSelectAccessible.h
@@ -21,7 +21,7 @@
*
* Contributor(s):
* Original Author: Eric Vaughan (evaughan@netscape.com)
- *
+ * Contributor(s): Kyle Yuan (kyle.yuan@sun.com)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@@ -41,6 +41,8 @@
#include "nsCOMPtr.h"
#include "nsIAccessibleSelectable.h"
+#include "nsIDOMHTMLCollection.h"
+#include "nsIDOMHTMLOptionElement.h"
#include "nsIDOMNode.h"
#include "nsIWeakReference.h"
#include "nsSelectAccessible.h"
@@ -69,6 +71,48 @@
/** First, the common widgets */
/** ------------------------------------------------------ */
+/*
+ * The basic implemetation of nsIAccessibleSelectable.
+ */
+class nsHTMLSelectableAccessible : public nsAccessible,
+ public nsIAccessibleSelectable
+{
+public:
+
+ NS_DECL_ISUPPORTS_INHERITED
+ NS_DECL_NSIACCESSIBLESELECTABLE
+
+ nsHTMLSelectableAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell);
+ virtual ~nsHTMLSelectableAccessible() {}
+
+protected:
+
+ NS_IMETHOD ChangeSelection(PRInt32 aIndex, PRUint8 aMethod, PRBool *aSelState);
+
+ class iterator
+ {
+ protected:
+ PRUint32 mLength;
+ PRUint32 mIndex;
+ PRInt32 mSelCount;
+ nsHTMLSelectableAccessible *mParent;
+ nsCOMPtr mOptions;
+ nsCOMPtr mOption;
+
+ public:
+ iterator(nsHTMLSelectableAccessible *aParent);
+
+ void CalcSelectionCount(PRInt32 *aSelectionCount);
+ void Select(PRBool aSelect);
+ void AddAccessibleIfSelected(nsIAccessibilityService *aAccService, nsISupportsArray *aSelectedAccessibles, nsIPresContext *aContext);
+ PRBool GetAccessibleIfSelected(PRInt32 aIndex, nsIAccessibilityService *aAccService, nsIPresContext *aContext, nsIAccessible **_retval);
+
+ PRBool Advance();
+ };
+
+ friend class iterator;
+};
+
/*
* The list that contains all the options in the select.
*/
@@ -132,16 +176,18 @@ public:
/*
* A class the represents the HTML Listbox widget.
*/
-class nsHTMLListboxAccessible : public nsListboxAccessible
+class nsHTMLListboxAccessible : public nsHTMLSelectableAccessible
{
public:
- NS_DECL_NSIACCESSIBLESELECTABLE
-
nsHTMLListboxAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell);
virtual ~nsHTMLListboxAccessible() {}
/* ----- nsIAccessible ----- */
+ NS_IMETHOD GetAccRole(PRUint32 *_retval);
+ NS_IMETHOD GetAccChildCount(PRInt32 *_retval);
+ NS_IMETHOD GetAccState(PRUint32 *_retval);
+
NS_IMETHOD GetAccLastChild(nsIAccessible **_retval);
NS_IMETHOD GetAccFirstChild(nsIAccessible **_retval);
NS_IMETHOD GetAccValue(nsAString& _retval);
@@ -155,7 +201,7 @@ public:
/*
* A class the represents the HTML Combobox widget.
*/
-class nsHTMLComboboxAccessible : public nsComboboxAccessible
+class nsHTMLComboboxAccessible : public nsHTMLSelectableAccessible
{
public:
@@ -163,6 +209,10 @@ public:
virtual ~nsHTMLComboboxAccessible() {}
/* ----- nsIAccessible ----- */
+ NS_IMETHOD GetAccRole(PRUint32 *_retval);
+ NS_IMETHOD GetAccChildCount(PRInt32 *_retval);
+ NS_IMETHOD GetAccState(PRUint32 *_retval);
+
NS_IMETHOD GetAccLastChild(nsIAccessible **_retval);
NS_IMETHOD GetAccFirstChild(nsIAccessible **_retval);
NS_IMETHOD GetAccValue(nsAString& _retval);
diff --git a/accessible/src/xul/nsXULSelectAccessible.cpp b/accessible/src/xul/nsXULSelectAccessible.cpp
index c280ab113fda..9eebc7ddff5e 100644
--- a/accessible/src/xul/nsXULSelectAccessible.cpp
+++ b/accessible/src/xul/nsXULSelectAccessible.cpp
@@ -21,7 +21,7 @@
*
* Contributor(s):
* Original Author: Eric Vaughan (evaughan@netscape.com)
- *
+ * Kyle Yuan (kyle.yuan@sun.com)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@@ -42,6 +42,7 @@
#include "nsIAccessibilityService.h"
#include "nsIDOMEventReceiver.h"
#include "nsIDOMNodeList.h"
+#include "nsIDOMXULMenuListElement.h"
#include "nsIDOMXULMultSelectCntrlEl.h"
#include "nsIDOMXULSelectCntrlItemEl.h"
#include "nsIDOMXULSelectCntrlEl.h"
@@ -68,6 +69,192 @@
* - nsXULSelectOptionAccessible
*/
+/** ------------------------------------------------------ */
+/** Impl. of nsXULSelectableAccessible */
+/** ------------------------------------------------------ */
+
+// Helper methos
+nsXULSelectableAccessible::nsXULSelectableAccessible(nsIDOMNode* aDOMNode,
+ nsIWeakReference* aShell):
+nsAccessible(aDOMNode, aShell)
+{
+}
+
+NS_IMPL_ISUPPORTS_INHERITED1(nsXULSelectableAccessible, nsAccessible, nsIAccessibleSelectable)
+
+NS_IMETHODIMP nsXULSelectableAccessible::ChangeSelection(PRInt32 aIndex, PRUint8 aMethod, PRBool *aSelState)
+{
+ *aSelState = PR_FALSE;
+
+ nsCOMPtr xulMultiSelect(do_QueryInterface(mDOMNode));
+ if (xulMultiSelect) {
+ nsCOMPtr nodeList;
+ xulMultiSelect->GetChildNodes(getter_AddRefs(nodeList));
+ if (nodeList) {
+ nsCOMPtr node;
+ nodeList->Item(aIndex, getter_AddRefs(node));
+ nsCOMPtr item(do_QueryInterface(node));
+ item->GetSelected(aSelState);
+ if (eSelection_Add == aMethod && !(*aSelState))
+ xulMultiSelect->AddItemToSelection(item);
+ else if (eSelection_Remove == aMethod && (*aSelState))
+ xulMultiSelect->RemoveItemFromSelection(item);
+ }
+ return NS_OK;
+ }
+
+ nsCOMPtr xulSelect(do_QueryInterface(mDOMNode));
+ if (xulSelect) {
+ PRInt32 selIndex;
+ xulSelect->GetSelectedIndex(&selIndex);
+ if (selIndex == aIndex)
+ *aSelState = PR_TRUE;
+ if (eSelection_Add == aMethod && !(*aSelState))
+ xulSelect->SetSelectedIndex(aIndex);
+ else if (eSelection_Remove == aMethod && (*aSelState)) {
+ xulSelect->SetSelectedIndex(-1);
+ }
+ return NS_OK;
+ }
+
+ return NS_ERROR_FAILURE;
+}
+
+// Interface methods
+NS_IMETHODIMP nsXULSelectableAccessible::GetSelectedChildren(nsISupportsArray **_retval)
+{
+ *_retval = nsnull;
+
+ nsCOMPtr accService(do_GetService("@mozilla.org/accessibilityService;1"));
+ if (!accService)
+ return NS_ERROR_FAILURE;
+
+ nsCOMPtr selectedAccessibles;
+ NS_NewISupportsArray(getter_AddRefs(selectedAccessibles));
+ if (!selectedAccessibles)
+ return NS_ERROR_OUT_OF_MEMORY;
+
+ // For XUL multi-select control
+ nsCOMPtr xulMultiSelect(do_QueryInterface(mDOMNode));
+ if (xulMultiSelect) {
+ PRInt32 length = 0;
+ xulMultiSelect->GetSelectedCount(&length);
+ for (PRInt32 index = 0; index < length; index++) {
+ nsCOMPtr tempAccessible;
+ nsCOMPtr tempNode;
+ xulMultiSelect->GetSelectedItem(index, getter_AddRefs(tempNode));
+ nsCOMPtr tempDOMNode (do_QueryInterface(tempNode));
+ accService->CreateXULListitemAccessible(tempDOMNode, getter_AddRefs(tempAccessible));
+ if (tempAccessible)
+ selectedAccessibles->AppendElement(tempAccessible);
+ }
+ }
+
+ PRUint32 uLength = 0;
+ selectedAccessibles->Count(&uLength);
+ if (uLength != 0) { // length of nsISupportsArray containing selected options
+ *_retval = selectedAccessibles;
+ NS_ADDREF(*_retval);
+ }
+
+ return NS_OK;
+}
+
+// return the nth selected child's nsIAccessible object
+NS_IMETHODIMP nsXULSelectableAccessible::RefSelection(PRInt32 aIndex, nsIAccessible **_retval)
+{
+ *_retval = nsnull;
+
+ nsCOMPtr accService(do_GetService("@mozilla.org/accessibilityService;1"));
+ if (!accService)
+ return NS_ERROR_FAILURE;
+
+ nsCOMPtr tempDOMNode;
+ nsCOMPtr xulMultiSelect(do_QueryInterface(mDOMNode));
+ if (xulMultiSelect)
+ xulMultiSelect->GetSelectedItem(aIndex, getter_AddRefs(tempDOMNode));
+
+ nsCOMPtr xulSelect(do_QueryInterface(mDOMNode));
+ if (xulSelect && aIndex == 0)
+ xulSelect->GetSelectedItem(getter_AddRefs(tempDOMNode));
+
+ if (tempDOMNode) {
+ nsCOMPtr tempAccess;
+ accService->CreateXULListitemAccessible(tempDOMNode, getter_AddRefs(tempAccess));
+ *_retval = tempAccess;
+ NS_ADDREF(*_retval);
+ return NS_OK;
+ }
+
+ return NS_ERROR_FAILURE;
+}
+
+NS_IMETHODIMP nsXULSelectableAccessible::GetSelectionCount(PRInt32 *aSelectionCount)
+{
+ *aSelectionCount = 0;
+
+ // For XUL multi-select control
+ nsCOMPtr xulMultiSelect(do_QueryInterface(mDOMNode));
+ if (xulMultiSelect)
+ return xulMultiSelect->GetSelectedCount(aSelectionCount);
+
+ // For XUL single-select control/menulist
+ nsCOMPtr xulSelect(do_QueryInterface(mDOMNode));
+ if (xulSelect) {
+ PRInt32 index;
+ xulSelect->GetSelectedIndex(&index);
+ if (index >= 0)
+ *aSelectionCount = 1;
+ return NS_OK;
+ }
+
+ return NS_ERROR_FAILURE;
+}
+
+NS_IMETHODIMP nsXULSelectableAccessible::AddSelection(PRInt32 aIndex)
+{
+ PRBool isSelected;
+ return ChangeSelection(aIndex, eSelection_Add, &isSelected);
+}
+
+NS_IMETHODIMP nsXULSelectableAccessible::RemoveSelection(PRInt32 aIndex)
+{
+ PRBool isSelected;
+ return ChangeSelection(aIndex, eSelection_Remove, &isSelected);
+}
+
+NS_IMETHODIMP nsXULSelectableAccessible::IsChildSelected(PRInt32 aIndex, PRBool *_retval)
+{
+ *_retval = PR_FALSE;
+ return ChangeSelection(aIndex, eSelection_GetState, _retval);
+}
+
+NS_IMETHODIMP nsXULSelectableAccessible::ClearSelection()
+{
+ nsCOMPtr xulMultiSelect(do_QueryInterface(mDOMNode));
+ if (xulMultiSelect)
+ return xulMultiSelect->ClearSelection();
+
+ nsCOMPtr xulSelect(do_QueryInterface(mDOMNode));
+ if (xulSelect)
+ return xulSelect->SetSelectedIndex(-1);
+
+ return NS_ERROR_FAILURE;
+}
+
+NS_IMETHODIMP nsXULSelectableAccessible::SelectAllSelection(PRBool *_retval)
+{
+ *_retval = PR_TRUE;
+
+ nsCOMPtr xulMultiSelect(do_QueryInterface(mDOMNode));
+ if (xulMultiSelect)
+ return xulMultiSelect->SelectAll();
+
+ // otherwise, don't support this method
+ *_retval = PR_FALSE;
+ return NS_OK;
+}
+
/** ------------------------------------------------------ */
/** First, the common widgets */
/** ------------------------------------------------------ */
@@ -147,7 +334,7 @@ NS_IMETHODIMP nsXULSelectOptionAccessible::GetAccState(PRUint32 *_retval)
/** Constructor */
nsXULListboxAccessible::nsXULListboxAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell):
-nsListboxAccessible(aDOMNode, aShell)
+nsXULSelectableAccessible(aDOMNode, aShell)
{
}
@@ -168,7 +355,9 @@ NS_IMETHODIMP nsXULListboxAccessible::GetAccChildCount(PRInt32 *_retval)
NS_IMETHODIMP nsXULListboxAccessible::GetAccState(PRUint32 *_retval)
{
// Get focus status from base class
- nsListboxAccessible::GetAccState(_retval);
+ nsAccessible::GetAccState(_retval);
+
+ *_retval |= STATE_READONLY | STATE_FOCUSABLE;
// see if we are multiple select if so set ourselves as such
nsCOMPtr element (do_QueryInterface(mDOMNode));
@@ -205,55 +394,6 @@ NS_IMETHODIMP nsXULListboxAccessible::GetAccRole(PRUint32 *_retval)
return NS_OK;
}
-/**
- * nsIAccessibleSelectable method.
- * - gets from the Select DOMNode the list of all Select Options
- * - iterates through all of the options looking for selected Options
- * - creates IAccessible objects for selected Options
- * - Returns the IAccessibles for selected Options in the nsISupportsArray
- *
- * retval will be nsnull if:
- * - there are no Options in the Select Element
- * - there are Options but none are selected
- * - the DOMNode is not a nsIDOMXULSelectControlElement ( shouldn't happen )
- */
-NS_IMETHODIMP nsXULListboxAccessible::GetSelectedChildren(nsISupportsArray **_retval)
-{
- *_retval = nsnull;
-
- nsCOMPtr accService(do_GetService("@mozilla.org/accessibilityService;1"));
- nsCOMPtr selectedAccessibles;
- NS_NewISupportsArray(getter_AddRefs(selectedAccessibles));
- if (!selectedAccessibles || !accService)
- return NS_ERROR_FAILURE;
-
- nsCOMPtr selectedItems;
- nsCOMPtr listbox (do_QueryInterface(mDOMNode));
- PRInt32 length = 0;
- if (listbox) {
- listbox->GetSelectedCount(&length);
- for ( PRInt32 i = 0 ; i < length ; i++ ) {
- nsCOMPtr tempAccessible;
- nsCOMPtr tempNode;
- listbox->GetSelectedItem(i, getter_AddRefs(tempNode));
- nsCOMPtr tempDOMNode (do_QueryInterface(tempNode));
- accService->CreateXULListitemAccessible(tempDOMNode, getter_AddRefs(tempAccessible));
- if (tempAccessible)
- selectedAccessibles->AppendElement(tempAccessible);
- }
- }
-
- PRUint32 uLength = 0;
- selectedAccessibles->Count(&uLength);
- if ( uLength != 0 ) { // length of nsISupportsArray containing selected options
- *_retval = selectedAccessibles;
- NS_ADDREF(*_retval);
- }
-
- // no options, not a select or none of the options are selected
- return NS_OK;
-}
-
/** ----- nsXULListitemAccessible ----- */
/** Constructor */
@@ -335,10 +475,55 @@ NS_IMETHODIMP nsXULListitemAccessible::GetAccState(PRUint32 *_retval)
/** Constructor */
nsXULComboboxAccessible::nsXULComboboxAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell):
-nsComboboxAccessible(aDOMNode, aShell)
+nsXULSelectableAccessible(aDOMNode, aShell)
{
}
+/** We are a combobox */
+NS_IMETHODIMP nsXULComboboxAccessible::GetAccRole(PRUint32 *_retval)
+{
+ *_retval = ROLE_COMBOBOX;
+ return NS_OK;
+}
+
+/**
+ * We always have 3 children: TextField, Button, Window. In that order
+ */
+NS_IMETHODIMP nsXULComboboxAccessible::GetAccChildCount(PRInt32 *_retval)
+{
+ *_retval = 3;
+ return NS_OK;
+}
+
+/**
+ * As a nsComboboxAccessible we can have the following states:
+ * STATE_FOCUSED
+ * STATE_READONLY
+ * STATE_FOCUSABLE
+ * STATE_HASPOPUP
+ * STATE_EXPANDED
+ * STATE_COLLAPSED
+ */
+NS_IMETHODIMP nsXULComboboxAccessible::GetAccState(PRUint32 *_retval)
+{
+ // Get focus status from base class
+ nsAccessible::GetAccState(_retval);
+
+ nsCOMPtr menuList(do_QueryInterface(mDOMNode));
+ if (menuList) {
+ PRBool isOpen;
+ menuList->GetOpen(&isOpen);
+ if (isOpen)
+ *_retval |= STATE_EXPANDED;
+ else
+ *_retval |= STATE_COLLAPSED;
+ }
+
+ *_retval |= STATE_HASPOPUP | STATE_READONLY | STATE_FOCUSABLE;
+
+ return NS_OK;
+}
+
/**
* Our value is the value of our ( first ) selected child. nsIDOMXULSelectElement
* returns this by default with GetValue().
@@ -353,5 +538,3 @@ NS_IMETHODIMP nsXULComboboxAccessible::GetAccValue(nsAString& _retval)
}
return NS_ERROR_FAILURE;
}
-
-
diff --git a/accessible/src/xul/nsXULSelectAccessible.h b/accessible/src/xul/nsXULSelectAccessible.h
index 4d1b997507d8..dcdbe596116c 100644
--- a/accessible/src/xul/nsXULSelectAccessible.h
+++ b/accessible/src/xul/nsXULSelectAccessible.h
@@ -21,7 +21,7 @@
*
* Contributor(s):
* Original Author: Eric Vaughan (evaughan@netscape.com)
- *
+ * Contributor(s): Kyle Yuan (kyle.yuan@sun.com)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@@ -70,6 +70,23 @@
/** First, the common widgets */
/** ------------------------------------------------------ */
+/*
+ * The basic implemetation of nsIAccessibleSelectable.
+ */
+class nsXULSelectableAccessible : public nsAccessible,
+ public nsIAccessibleSelectable
+{
+public:
+ NS_DECL_ISUPPORTS_INHERITED
+ NS_DECL_NSIACCESSIBLESELECTABLE
+
+ nsXULSelectableAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell);
+ virtual ~nsXULSelectableAccessible() {}
+
+protected:
+ NS_IMETHOD ChangeSelection(PRInt32 aIndex, PRUint8 aMethod, PRBool *aSelState);
+};
+
/*
* The list that contains all the options in the select.
*/
@@ -109,12 +126,10 @@ public:
/*
* A class the represents the XUL Listbox widget.
*/
-class nsXULListboxAccessible : public nsListboxAccessible
+class nsXULListboxAccessible : public nsXULSelectableAccessible
{
public:
- NS_DECL_NSIACCESSIBLESELECTABLE
-
nsXULListboxAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell);
virtual ~nsXULListboxAccessible() {}
@@ -151,7 +166,7 @@ public:
/*
* A class the represents the XUL Combobox widget.
*/
-class nsXULComboboxAccessible : public nsComboboxAccessible
+class nsXULComboboxAccessible : public nsXULSelectableAccessible
{
public:
@@ -159,6 +174,10 @@ public:
virtual ~nsXULComboboxAccessible() {}
/* ----- nsIAccessible ----- */
+ NS_IMETHOD GetAccRole(PRUint32 *_retval);
+ NS_IMETHOD GetAccChildCount(PRInt32 *_retval);
+ NS_IMETHOD GetAccState(PRUint32 *_retval);
+
NS_IMETHOD GetAccValue(nsAString& _retval);
};
diff --git a/accessible/src/xul/nsXULTreeAccessible.cpp b/accessible/src/xul/nsXULTreeAccessible.cpp
index 528e59353910..bd9da7dbf6d7 100644
--- a/accessible/src/xul/nsXULTreeAccessible.cpp
+++ b/accessible/src/xul/nsXULTreeAccessible.cpp
@@ -50,7 +50,7 @@
// ---------- nsXULTreeAccessible ----------
nsXULTreeAccessible::nsXULTreeAccessible(nsIDOMNode *aDOMNode, nsIWeakReference *aShell):
-nsAccessible(aDOMNode, aShell)
+nsXULSelectableAccessible(aDOMNode, aShell)
{
GetTreeBoxObject(aDOMNode, getter_AddRefs(mTree));
if (mTree)
@@ -58,7 +58,7 @@ nsAccessible(aDOMNode, aShell)
NS_ASSERTION(mTree && mTreeView, "Can't get mTree or mTreeView!\n");
}
-NS_IMPL_ISUPPORTS_INHERITED1(nsXULTreeAccessible, nsAccessible, nsIAccessibleSelectable)
+NS_IMPL_ISUPPORTS_INHERITED0(nsXULTreeAccessible, nsXULSelectableAccessible)
NS_IMETHODIMP nsXULTreeAccessible::GetAccState(PRUint32 *_retval)
{
@@ -68,10 +68,11 @@ NS_IMETHODIMP nsXULTreeAccessible::GetAccState(PRUint32 *_retval)
// see if we are multiple select if so set ourselves as such
nsCOMPtr element (do_QueryInterface(mDOMNode));
if (element) {
+ // the default selection type is multiple
nsAutoString selType;
element->GetAttribute(NS_LITERAL_STRING("seltype"), selType);
- if (!selType.IsEmpty() && selType.Equals(NS_LITERAL_STRING("multiple")))
- *_retval |= STATE_MULTISELECTABLE;
+ if (selType.IsEmpty() || !selType.Equals(NS_LITERAL_STRING("single")))
+ *_retval |= STATE_MULTISELECTABLE;
}
*_retval |= STATE_READONLY | STATE_FOCUSABLE;
@@ -201,6 +202,121 @@ NS_IMETHODIMP nsXULTreeAccessible::GetSelectedChildren(nsISupportsArray **_retva
return NS_OK;
}
+NS_IMETHODIMP nsXULTreeAccessible::GetSelectionCount(PRInt32 *aSelectionCount)
+{
+ *aSelectionCount = 0;
+
+ NS_ENSURE_TRUE(mTree && mTreeView, NS_ERROR_FAILURE);
+
+ nsCOMPtr selection;
+ mTree->GetSelection(getter_AddRefs(selection));
+ if (selection)
+ selection->GetCount(aSelectionCount);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsXULTreeAccessible::ChangeSelection(PRInt32 aIndex, PRUint8 aMethod, PRBool *aSelState)
+{
+ NS_ENSURE_TRUE(mTree && mTreeView, NS_ERROR_FAILURE);
+
+ nsCOMPtr selection;
+ mTree->GetSelection(getter_AddRefs(selection));
+ if (selection) {
+ selection->IsSelected(aIndex, aSelState);
+ if ((!(*aSelState) && eSelection_Add == aMethod) ||
+ ((*aSelState) && eSelection_Remove == aMethod))
+ selection->ToggleSelect(aIndex);
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsXULTreeAccessible::AddSelection(PRInt32 aIndex)
+{
+ PRBool isSelected;
+ return ChangeSelection(aIndex, eSelection_Add, &isSelected);
+}
+
+NS_IMETHODIMP nsXULTreeAccessible::RemoveSelection(PRInt32 aIndex)
+{
+ PRBool isSelected;
+ return ChangeSelection(aIndex, eSelection_Remove, &isSelected);
+}
+
+NS_IMETHODIMP nsXULTreeAccessible::IsChildSelected(PRInt32 aIndex, PRBool *_retval)
+{
+ return ChangeSelection(aIndex, eSelection_GetState, _retval);
+}
+
+NS_IMETHODIMP nsXULTreeAccessible::ClearSelection()
+{
+ NS_ENSURE_TRUE(mTree && mTreeView, NS_ERROR_FAILURE);
+
+ nsCOMPtr selection;
+ mTree->GetSelection(getter_AddRefs(selection));
+ if (selection)
+ selection->ClearSelection();
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsXULTreeAccessible::RefSelection(PRInt32 aIndex, nsIAccessible **_retval)
+{
+ *_retval = nsnull;
+
+ NS_ENSURE_TRUE(mTree && mTreeView, NS_ERROR_FAILURE);
+
+ nsCOMPtr selection;
+ mTree->GetSelection(getter_AddRefs(selection));
+ if (!selection)
+ return NS_ERROR_FAILURE;
+
+ PRInt32 rowIndex, rowCount;
+ PRInt32 selCount = 0;
+ PRBool isSelected;
+ mTreeView->GetRowCount(&rowCount);
+ for (rowIndex = 0; rowIndex < rowCount; rowIndex++) {
+ selection->IsSelected(rowIndex, &isSelected);
+ if (isSelected) {
+ if (selCount == aIndex) {
+ nsCOMPtr tempAccess;
+ tempAccess = new nsXULTreeitemAccessible(this, mDOMNode, mPresShell, rowIndex);
+ if (!tempAccess)
+ return NS_ERROR_OUT_OF_MEMORY;
+ *_retval = tempAccess;
+ NS_ADDREF(*_retval);
+ }
+ selCount++;
+ }
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsXULTreeAccessible::SelectAllSelection(PRBool *_retval)
+{
+ *_retval = PR_FALSE;
+
+ NS_ENSURE_TRUE(mTree && mTreeView, NS_ERROR_FAILURE);
+
+ // see if we are multiple select if so set ourselves as such
+ nsCOMPtr element (do_QueryInterface(mDOMNode));
+ if (element) {
+ nsAutoString selType;
+ element->GetAttribute(NS_LITERAL_STRING("seltype"), selType);
+ if (selType.IsEmpty() || !selType.Equals(NS_LITERAL_STRING("single"))) {
+ *_retval = PR_TRUE;
+ nsCOMPtr selection;
+ mTree->GetSelection(getter_AddRefs(selection));
+ if (selection)
+ selection->SelectAll();
+ }
+ }
+
+ return NS_OK;
+}
+
// Get the nsITreeBoxObject interface from any levels DOMNode under the
void nsXULTreeAccessible::GetTreeBoxObject(nsIDOMNode *aDOMNode, nsITreeBoxObject **aBoxObject)
{
diff --git a/accessible/src/xul/nsXULTreeAccessible.h b/accessible/src/xul/nsXULTreeAccessible.h
index dd4b2d8346d8..e04b3cabe992 100644
--- a/accessible/src/xul/nsXULTreeAccessible.h
+++ b/accessible/src/xul/nsXULTreeAccessible.h
@@ -42,17 +42,16 @@
#include "nsAccessible.h"
#include "nsBaseWidgetAccessible.h"
#include "nsCOMPtr.h"
-#include "nsIAccessibleSelectable.h"
#include "nsIDOMNode.h"
#include "nsIWeakReference.h"
#include "nsITreeBoxObject.h"
#include "nsITreeView.h"
+#include "nsXULSelectAccessible.h"
/*
* A class the represents the XUL Tree widget.
*/
-class nsXULTreeAccessible : public nsAccessible,
- public nsIAccessibleSelectable
+class nsXULTreeAccessible : public nsXULSelectableAccessible
{
public:
NS_DECL_ISUPPORTS_INHERITED
@@ -75,6 +74,8 @@ public:
private:
nsCOMPtr mTree;
nsCOMPtr mTreeView;
+
+ NS_IMETHOD ChangeSelection(PRInt32 aIndex, PRUint8 aMethod, PRBool *aSelState);
};
/**