diff --git a/mozilla/accessible/src/Makefile.in b/mozilla/accessible/src/Makefile.in index d7b69b9debe..0d2767ab0f8 100644 --- a/mozilla/accessible/src/Makefile.in +++ b/mozilla/accessible/src/Makefile.in @@ -52,21 +52,21 @@ REQUIRES = xpcom \ CPPSRCS = \ nsAccessible.cpp \ nsAccessibilityService.cpp \ - nsRootAccessible.cpp \ - nsHTMLIFrameRootAccessible.cpp \ - nsHTMLFormControlAccessible.cpp \ - nsHTMLTextAccessible.cpp \ - nsHTMLTableAccessible.cpp \ - nsHTMLImageAccessible.cpp \ - nsHTMLAreaAccessible.cpp \ - nsHTMLLinkAccessible.cpp \ - nsHTMLSelectListAccessible.cpp \ - nsHTMLComboboxAccessible.cpp \ - nsHTMLListboxAccessible.cpp \ + nsBaseWidgetAccessible.cpp \ + nsFormControlAccessible.cpp \ nsGenericAccessible.cpp \ + nsHTMLAreaAccessible.cpp \ + nsHTMLFormControlAccessible.cpp \ + nsHTMLIFrameRootAccessible.cpp \ + nsHTMLImageAccessible.cpp \ + nsHTMLLinkAccessible.cpp \ + nsHTMLSelectAccessible.cpp \ + nsHTMLTableAccessible.cpp \ + nsHTMLTextAccessible.cpp \ + nsRootAccessible.cpp \ + nsSelectAccessible.cpp \ nsXULFormControlAccessible.cpp \ nsXULTextAccessible.cpp \ - nsBaseWidgetAccessible.cpp \ $(NULL) EXPORTS = \ diff --git a/mozilla/accessible/src/base/nsAccessibilityService.cpp b/mozilla/accessible/src/base/nsAccessibilityService.cpp index e351163a13c..b7069437458 100644 --- a/mozilla/accessible/src/base/nsAccessibilityService.cpp +++ b/mozilla/accessible/src/base/nsAccessibilityService.cpp @@ -57,9 +57,7 @@ #include "nsHTMLImageAccessible.h" #include "nsHTMLAreaAccessible.h" #include "nsHTMLLinkAccessible.h" -#include "nsHTMLSelectListAccessible.h" -#include "nsHTMLComboboxAccessible.h" -#include "nsHTMLListboxAccessible.h" +#include "nsHTMLSelectAccessible.h" #include "nsIDOMHTMLAreaElement.h" #include "nsHTMLFormControlAccessible.h" #include "nsIAccessibleProvider.h" @@ -76,7 +74,9 @@ #include "nsIDocShell.h" #include "nsHTMLIFrameRootAccessible.h" -//-------------------- +/** + * nsAccessibility Service + */ nsAccessibilityService::nsAccessibilityService() { @@ -89,9 +89,6 @@ nsAccessibilityService::~nsAccessibilityService() NS_IMPL_THREADSAFE_ISUPPORTS1(nsAccessibilityService, nsIAccessibilityService); - - - //////////////////////////////////////////////////////////////////////////////// // nsIAccessibilityService methods: @@ -322,7 +319,7 @@ NS_IMETHODIMP nsAccessibilityService::CreateXULTextAccessible(nsIDOMNode *aNode, // reusing the HTML accessible widget and enhancing for XUL *_retval = new nsXULTextAccessible(aNode, weakShell); - if (! *_retval) + if (! *_retval) return NS_ERROR_OUT_OF_MEMORY; NS_ADDREF(*_retval); @@ -595,7 +592,6 @@ nsAccessibilityService::CreateHTMLIFrameAccessible(nsIDOMNode* aDOMNode, nsISupp return NS_ERROR_FAILURE; } - void nsAccessibilityService::GetOwnerFor(nsIPresShell *aPresShell, nsIPresShell **aOwnerShell, nsIContent **aOwnerContent) { nsCOMPtr presContext; @@ -646,10 +642,9 @@ void nsAccessibilityService::GetOwnerFor(nsIPresShell *aPresShell, nsIPresShell } } -/* ------------------------------------------------------- - * GetAccessibleFor - get an nsIAccessible from a DOM node - * ------------------------------------------------------- */ - +/** + * GetAccessibleFor - get an nsIAccessible from a DOM node + */ NS_IMETHODIMP nsAccessibilityService::GetAccessibleFor(nsIDOMNode *aNode, nsIAccessible **_retval) { diff --git a/mozilla/accessible/src/base/nsAccessible.cpp b/mozilla/accessible/src/base/nsAccessible.cpp index 53b383f42b9..b832cd0ffee 100644 --- a/mozilla/accessible/src/base/nsAccessible.cpp +++ b/mozilla/accessible/src/base/nsAccessible.cpp @@ -80,6 +80,20 @@ #include "nsReadableUtils.h" #include "nsIBindingManager.h" +#include "nsFormControlAccessible.h" +#include "nsIDOMHTMLFormElement.h" +#include "nsIDOMHTMLInputElement.h" +#include "nsIDOMHTMLLabelElement.h" +#include "nsIDOMNodeList.h" +#include "nsIDOMXULButtonElement.h" +#include "nsIDOMXULCheckboxElement.h" +#include "nsIDOMXULDocument.h" +#include "nsIDOMXULElement.h" +#include "nsIDOMXULLabelElement.h" +#include "nsIDOMXULSelectCntrlEl.h" +#include "nsIDOMXULSelectCntrlItemEl.h" +#include "nsString.h" + // IFrame Helpers #include "nsIDocShell.h" #include "nsIWebShell.h" @@ -1324,3 +1338,194 @@ NS_IMETHODIMP nsAccessible::AppendFlatStringFromSubtree(nsIContent *aContent, ns } return NS_OK; } + +/** + * Called for XUL work only + * Checks the label's value first then makes a call to get the + * text from the children if the value is not set. + */ +NS_IMETHODIMP nsAccessible::AppendLabelText(nsIDOMNode *aLabelNode, nsAWritableString& _retval) +{ + NS_ASSERTION(aLabelNode, "Label Node passed in is null"); + nsCOMPtr labelNode(do_QueryInterface(aLabelNode)); + // label's value="foo" is set + if ( labelNode && NS_SUCCEEDED(labelNode->GetValue(_retval))) { + if (_retval.IsEmpty()) { + // label contains children who define it's text -- possibly HTML + nsCOMPtr content(do_QueryInterface(labelNode)); + if (content) + return AppendFlatStringFromSubtree(content, &_retval); + } + return NS_OK; + } + return NS_ERROR_FAILURE; +} + +/** + * Called for HTML work only + */ +NS_IMETHODIMP nsAccessible::AppendLabelFor(nsIContent *aLookNode, nsAReadableString *aId, nsAWritableString *aLabel) +{ + PRInt32 numChildren = 0; + + nsCOMPtr labelElement(do_QueryInterface(aLookNode)); + if (labelElement) { + nsCOMPtr elt(do_QueryInterface(aLookNode)); + nsresult rv = NS_OK; + + if (elt) { + nsAutoString labelIsFor; + elt->GetAttribute(NS_LITERAL_STRING("for"),labelIsFor); + if (labelIsFor.Equals(*aId)) + rv = AppendFlatStringFromSubtree(aLookNode, aLabel); + } + return rv; + } + + aLookNode->ChildCount(numChildren); + nsIContent *contentWalker; + PRInt32 index; + for (index = 0; index < numChildren; index++) { + aLookNode->ChildAt(index, contentWalker); + if (contentWalker) + AppendLabelFor(contentWalker, aId, aLabel); + } + return NS_OK; +} + +/** + * Only called if the element is not a nsIDOMXULControlElement. Initially walks up + * the DOM tree to the form, concatonating label elements as it goes. Then checks for + * labels with the for="controlID" property. + */ +NS_IMETHODIMP nsAccessible::GetHTMLAccName(nsAWritableString& _retval) +{ + nsCOMPtr walkUpContent(do_QueryInterface(mDOMNode)); + nsCOMPtr labelElement; + nsCOMPtr formElement; + nsresult rv = NS_OK; + + nsAutoString label; + // go up tree get name of ancestor label if there is one. Don't go up farther than form element + while (walkUpContent && label.IsEmpty() && !formElement) { + labelElement = do_QueryInterface(walkUpContent); + if (labelElement) + rv = AppendFlatStringFromSubtree(walkUpContent, &label); + formElement = do_QueryInterface(walkUpContent); // reached top ancestor in form + nsCOMPtr nextParent; + walkUpContent->GetParent(*getter_AddRefs(nextParent)); + walkUpContent = nextParent; + } + + + // There can be a label targeted at this control using the for="control_id" attribute + // To save computing time, only look for those inside of a form element + walkUpContent = do_QueryInterface(formElement); + + if (walkUpContent) { + nsCOMPtr elt(do_QueryInterface(mDOMNode)); + nsAutoString forId; + elt->GetAttribute(NS_LITERAL_STRING("id"), forId); + // Actually we'll be walking down the content this time, with a depth first search + if (!forId.IsEmpty()) + AppendLabelFor(walkUpContent,&forId,&label); + } + + label.CompressWhitespace(); + if (label.IsEmpty()) + return nsAccessible::GetAccName(_retval); + + _retval.Assign(label); + + return NS_OK; +} + +/** + * 3 main cases for XUL Controls to be labeled + * 1 - control contains label="foo" + * 2 - control has, as a child, a label element + * - label has either value="foo" or children + * 3 - non-child label contains control="controlID" + * - label has either value="foo" or children + * Once a label is found, the search is discontinued, so a control + * that has a label child as well as having a label external to + * the control that uses the control="controlID" syntax will use + * the child label for its Name. + */ +/* wstring getAccName (); */ +NS_IMETHODIMP nsAccessible::GetXULAccName(nsAWritableString& _retval) +{ + nsresult rv; + nsAutoString label; + + // CASE #1 -- great majority of the cases + nsCOMPtr domElement(do_QueryInterface(mDOMNode)); + NS_ASSERTION(domElement, "No domElement for accessible DOM node!"); + rv = domElement->GetAttribute(NS_LITERAL_STRING("label"), label) ; + + if (NS_FAILED(rv) || label.IsEmpty() ) { + + // CASE #2 ------ label as a child + nsCOMPtrlabelChildren; + NS_ASSERTION(domElement, "No domElement for accessible DOM node!"); + if (NS_SUCCEEDED(rv = domElement->GetElementsByTagName(NS_LITERAL_STRING("label"), getter_AddRefs(labelChildren)))) { + PRUint32 length = 0; + if (NS_SUCCEEDED(rv = labelChildren->GetLength(&length)) && length > 0) { + for (PRUint32 i = 0; i < length; ++i) { + nsCOMPtr child; + if (NS_SUCCEEDED(rv = labelChildren->Item(i, getter_AddRefs(child) ))) { + rv = AppendLabelText(child, label); + } + } + } + } + + if (NS_FAILED(rv) || label.IsEmpty()) { + + // CASE #3 ----- non-child label pointing to control + // XXX jgaunt + // decided to search the parent's children for labels linked to + // this control via the control="controlID" syntax, instead of searching + // the entire document with: + // + // nsCOMPtr doc; + // nsCOMPtr content(do_QueryInterface(mDOMNode)); + // content->GetDocument(*getter_AddRefs(doc)); + // nsCOMPtr xulDoc(do_QueryInterface(doc)); + // if (xulDoc) { + // nsCOMPtrlabelList; + // if (NS_SUCCEEDED(rv = xulDoc->GetElementsByAttribute(NS_LITERAL_STRING("control"), controlID, getter_AddRefs(labelList)))) + // + // This should keep search times down and still get the relevant + // labels. + nsCOMPtr parent; + if (NS_SUCCEEDED(rv = mDOMNode->GetParentNode(getter_AddRefs(parent)))) { + nsCOMPtr xulElement(do_QueryInterface(parent)); + NS_ASSERTION(xulElement, "No xulElement for parent DOM Node!"); + if (xulElement) { + nsAutoString controlID; + nsCOMPtrlabelList; + if (NS_SUCCEEDED(rv = xulElement->GetElementsByAttribute(NS_LITERAL_STRING("control"), controlID, getter_AddRefs(labelList)))) + { + PRUint32 length = 0; + if (NS_SUCCEEDED(rv = labelList->GetLength(&length)) && length > 0) { + for (PRUint32 i = 0; i < length; ++i) { + nsCOMPtr child; + if (NS_SUCCEEDED(rv = labelList->Item(i, getter_AddRefs(child) ))) { + rv = AppendLabelText(child, label); + } + } + } + } + } + } // End of CASE #3 + } // END of CASE #2 + } // END of CASE #1 + + label.CompressWhitespace(); + if (label.IsEmpty()) + return nsAccessible::GetAccName(_retval); + + _retval.Assign(label); + return NS_OK; +} diff --git a/mozilla/accessible/src/base/nsAccessible.h b/mozilla/accessible/src/base/nsAccessible.h index 44ed93d349f..295416705a3 100644 --- a/mozilla/accessible/src/base/nsAccessible.h +++ b/mozilla/accessible/src/base/nsAccessible.h @@ -65,6 +65,12 @@ enum { eSiblingsUninitialized = -1, eSiblingsWalkNormalDOM = -2}; // Used in si class nsAccessible : public nsGenericAccessible { public: + + // to eliminate the confusion of "magic numbers" -- if ( 0 ){ foo; } + enum { eAction_Switch=0, eAction_Jump=0, eAction_Click=0 }; + // how many actions + enum { eNo_Action=0, eSingle_Action=1 }; + NS_IMETHOD GetAccName(nsAWritableString& _retval); NS_IMETHOD GetAccParent(nsIAccessible **_retval); NS_IMETHOD GetAccNextSibling(nsIAccessible **_retval); @@ -116,6 +122,12 @@ public: // helper method to verify frames static PRBool IsCorrectFrameType(nsIFrame* aFrame, nsIAtom* aAtom); +protected: + NS_IMETHOD AppendLabelText(nsIDOMNode *aLabelNode, nsAWritableString& _retval); + NS_IMETHOD AppendLabelFor(nsIContent *aLookNode, nsAReadableString *aId, nsAWritableString *aLabel); + NS_IMETHOD GetHTMLAccName(nsAWritableString& _retval); + NS_IMETHOD GetXULAccName(nsAWritableString& _retval); + protected: virtual nsIFrame* GetFrame(); virtual nsIFrame* GetBoundsFrame(); diff --git a/mozilla/accessible/src/base/nsBaseWidgetAccessible.cpp b/mozilla/accessible/src/base/nsBaseWidgetAccessible.cpp index df55a527ba9..4fb07be2ad7 100644 --- a/mozilla/accessible/src/base/nsBaseWidgetAccessible.cpp +++ b/mozilla/accessible/src/base/nsBaseWidgetAccessible.cpp @@ -43,6 +43,7 @@ #include "nsGUIEvent.h" #include "nsIContent.h" #include "nsIDOMElement.h" +#include "nsIDOMEventReceiver.h" #include "nsIFrame.h" #include "nsILink.h" #include "nsIPresContext.h" @@ -113,6 +114,53 @@ NS_IMETHODIMP nsBlockAccessible::AccGetAt(PRInt32 tx, PRInt32 ty, nsIAccessible return NS_OK; } +/** + * nsContainerAccessible + */ +nsContainerAccessible::nsContainerAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell): +nsAccessible(aNode, aShell) +{ +} + +/** no actions */ +NS_IMETHODIMP nsContainerAccessible::GetAccNumActions(PRUint8 *_retval) +{ + *_retval = eNo_Action; + return NS_OK; +} + +/** no actions */ +NS_IMETHODIMP nsContainerAccessible::GetAccActionName(PRUint8 index, nsAWritableString& _retval) +{ + return NS_OK; +} + +/** no actions */ +NS_IMETHODIMP nsContainerAccessible::AccDoAction(PRUint8 index) +{ + return NS_OK; +} + +/** no state -- normal */ +NS_IMETHODIMP nsContainerAccessible::GetAccState(PRUint32 *_retval) +{ + *_retval = 0; + return NS_OK; +} + +/** no value */ +NS_IMETHODIMP nsContainerAccessible::GetAccValue(nsAWritableString& _retval) +{ + return NS_OK; +} + +/** no name*/ +NS_IMETHODIMP nsContainerAccessible::GetAccName(nsAWritableString& _retval) +{ + return NS_OK; +} + + //------------- // nsLeafFrameAccessible //------------- @@ -209,7 +257,7 @@ NS_IMETHODIMP nsLinkableAccessible::GetAccValue(nsAWritableString& _retval) /* PRUint8 getAccNumActions (); */ NS_IMETHODIMP nsLinkableAccessible::GetAccNumActions(PRUint8 *_retval) { - *_retval = 1; + *_retval = eSingle_Action; return NS_OK; } @@ -217,7 +265,7 @@ NS_IMETHODIMP nsLinkableAccessible::GetAccNumActions(PRUint8 *_retval) NS_IMETHODIMP nsLinkableAccessible::GetAccActionName(PRUint8 index, nsAWritableString& _retval) { // Action 0 (default action): Jump to link - if (index == 0) { + if (index == eAction_Jump) { if (IsALink()) { _retval = NS_LITERAL_STRING("jump"); return NS_OK; @@ -292,39 +340,71 @@ PRBool nsLinkableAccessible::IsALink() } // ------------ -// Text Accessibles +// nsMenuListenerAccessible // ------------ -nsTextAccessible::nsTextAccessible(nsIDOMNode* aDomNode, nsIWeakReference* aShell): -nsLinkableAccessible(aDomNode, aShell) +NS_IMPL_ISUPPORTS_INHERITED1(nsMenuListenerAccessible, nsAccessible, nsIDOMXULListener) + +nsMenuListenerAccessible::nsMenuListenerAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell): +nsAccessible(aDOMNode, aShell) +{ + mRegistered = PR_FALSE; + mOpen = PR_FALSE; +} + +nsMenuListenerAccessible::~nsMenuListenerAccessible() +{ + if (mRegistered) { + nsCOMPtr eventReceiver(do_QueryInterface(mDOMNode)); + if (eventReceiver) + eventReceiver->RemoveEventListener(NS_LITERAL_STRING("popupshowing"), this, PR_TRUE); + } +} + +NS_IMETHODIMP nsMenuListenerAccessible::PopupShowing(nsIDOMEvent* aEvent) { + mOpen = PR_TRUE; + + /* TBD send state change event */ + + return NS_OK; } -/* unsigned long getAccRole (); */ -NS_IMETHODIMP nsTextAccessible::GetAccRole(PRUint32 *_retval) +NS_IMETHODIMP nsMenuListenerAccessible::PopupHiding(nsIDOMEvent* aEvent) +{ + mOpen = PR_FALSE; + + /* TBD send state change event */ + + return NS_OK; +} + +NS_IMETHODIMP nsMenuListenerAccessible::Close(nsIDOMEvent* aEvent) +{ + mOpen = PR_FALSE; + + /* TBD send state change event */ + + return NS_OK; +} + +void +nsMenuListenerAccessible::SetupMenuListener() { - *_retval = ROLE_TEXT; + // if not already one, register ourselves as a popup listener + if (!mRegistered) { + nsCOMPtr eventReceiver(do_QueryInterface(mDOMNode)); + if (!eventReceiver) { + return; + } - return NS_OK; + nsresult rv = eventReceiver->AddEventListener(NS_LITERAL_STRING("popupshowing"), this, PR_TRUE); + + if (NS_FAILED(rv)) { + return; + } + + mRegistered = PR_TRUE; + } } -/* nsIAccessible getAccFirstChild (); */ -NS_IMETHODIMP nsTextAccessible::GetAccFirstChild(nsIAccessible **_retval) -{ - *_retval = nsnull; - return NS_OK; -} - -/* nsIAccessible getAccLastChild (); */ -NS_IMETHODIMP nsTextAccessible::GetAccLastChild(nsIAccessible **_retval) -{ - *_retval = nsnull; - return NS_OK; -} - -/* long getAccChildCount (); */ -NS_IMETHODIMP nsTextAccessible::GetAccChildCount(PRInt32 *_retval) -{ - *_retval = 0; - return NS_OK; -} diff --git a/mozilla/accessible/src/base/nsBaseWidgetAccessible.h b/mozilla/accessible/src/base/nsBaseWidgetAccessible.h index 106ce5d2a0e..5b4162aeb9f 100644 --- a/mozilla/accessible/src/base/nsBaseWidgetAccessible.h +++ b/mozilla/accessible/src/base/nsBaseWidgetAccessible.h @@ -41,9 +41,10 @@ #define _nsBaseWidgetAccessible_H_ #include "nsAccessible.h" -#include "nsIDOMNode.h" #include "nsCOMPtr.h" #include "nsIContent.h" +#include "nsIDOMNode.h" +#include "nsIDOMXULListener.h" /** * This file contains a number of classes that are used as base @@ -57,8 +58,24 @@ class nsBlockAccessible : public nsAccessible { public: - nsBlockAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell); - NS_IMETHOD AccGetAt(PRInt32 x, PRInt32 y, nsIAccessible **_retval); + nsBlockAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell); + NS_IMETHOD AccGetAt(PRInt32 x, PRInt32 y, nsIAccessible **_retval); +}; + +/** + * Special Accessible that just contains other accessible objects + * no actions, no name, no state, no value + */ +class nsContainerAccessible : public nsAccessible +{ +public: + nsContainerAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell); + NS_IMETHOD GetAccNumActions(PRUint8 *_retval); + NS_IMETHOD GetAccActionName(PRUint8 index, nsAWritableString& _retval); + NS_IMETHOD AccDoAction(PRUint8 index); + NS_IMETHOD GetAccState(PRUint32 *_retval); + NS_IMETHOD GetAccValue(nsAWritableString& _retval); + NS_IMETHOD GetAccName(nsAWritableString& _retval); }; /** @@ -66,12 +83,11 @@ public: */ class nsLeafAccessible : public nsAccessible { - public: - nsLeafAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell); - - NS_IMETHOD GetAccFirstChild(nsIAccessible **_retval); - NS_IMETHOD GetAccLastChild(nsIAccessible **_retval); - NS_IMETHOD GetAccChildCount(PRInt32 *_retval); +public: + nsLeafAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell); + NS_IMETHOD GetAccFirstChild(nsIAccessible **_retval); + NS_IMETHOD GetAccLastChild(nsIAccessible **_retval); + NS_IMETHOD GetAccChildCount(PRInt32 *_retval); }; /** @@ -81,36 +97,52 @@ class nsLeafAccessible : public nsAccessible */ class nsLinkableAccessible : public nsAccessible { - public: - nsLinkableAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell); - NS_IMETHOD GetAccNumActions(PRUint8 *_retval); - NS_IMETHOD GetAccActionName(PRUint8 index, nsAWritableString& _retval); - NS_IMETHOD AccDoAction(PRUint8 index); - NS_IMETHOD GetAccState(PRUint32 *_retval); - NS_IMETHOD GetAccValue(nsAWritableString& _retval); - - protected: - PRBool IsALink(); - PRBool mIsALinkCached; // -1 = unknown, 0 = not a link, 1 = is a link - nsCOMPtr mLinkContent; - PRBool mIsLinkVisited; -}; - -/** - * Text nodes have no children, but since double inheritance - * no-worky we have to re-impl the LeafAccessiblity blocks - * this way. - */ -class nsTextAccessible : public nsLinkableAccessible -{ - public: - nsTextAccessible(nsIDOMNode* aDomNode, nsIWeakReference* aShell); - NS_IMETHOD GetAccRole(PRUint32 *_retval); - NS_IMETHOD GetAccFirstChild(nsIAccessible **_retval); - NS_IMETHOD GetAccLastChild(nsIAccessible **_retval); - NS_IMETHOD GetAccChildCount(PRInt32 *_retval); + nsLinkableAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell); + NS_IMETHOD GetAccNumActions(PRUint8 *_retval); + NS_IMETHOD GetAccActionName(PRUint8 index, nsAWritableString& _retval); + NS_IMETHOD AccDoAction(PRUint8 index); + NS_IMETHOD GetAccState(PRUint32 *_retval); + NS_IMETHOD GetAccValue(nsAWritableString& _retval); + +protected: + PRBool IsALink(); + PRBool mIsALinkCached; // -1 = unknown, 0 = not a link, 1 = is a link + nsCOMPtr mLinkContent; + PRBool mIsLinkVisited; }; +/* + * A base class that can listen to menu events. Its used by selects so the + * button and the window accessibles can change their name and role + * depending on whether the drop down list is dropped down on not + */ +class nsMenuListenerAccessible : public nsAccessible, public nsIDOMXULListener +{ +public: + + NS_DECL_ISUPPORTS_INHERITED + + nsMenuListenerAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell); + virtual ~nsMenuListenerAccessible(); + + // popup listener + 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(); + + PRBool mRegistered; + PRBool mOpen; +}; #endif + diff --git a/mozilla/accessible/src/base/nsFormControlAccessible.cpp b/mozilla/accessible/src/base/nsFormControlAccessible.cpp new file mode 100644 index 00000000000..a345ba58d83 --- /dev/null +++ b/mozilla/accessible/src/base/nsFormControlAccessible.cpp @@ -0,0 +1,226 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: NPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Netscape 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/NPL/ + * + * 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): + * John Gaunt (jgaunt@netscape.com) + * Aaron Leventhal (aaronl@netscape.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 + * 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 NPL, 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 NPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +// NOTE: alphabetically ordered +#include "nsFormControlAccessible.h" +#include "nsIDocument.h" +#include "nsIDOMHTMLFormElement.h" +#include "nsIDOMHTMLInputElement.h" +#include "nsIDOMHTMLLabelElement.h" +#include "nsIDOMNodeList.h" +#include "nsIDOMXULButtonElement.h" +#include "nsIDOMXULCheckboxElement.h" +#include "nsIDOMXULDocument.h" +#include "nsIDOMXULElement.h" +#include "nsIDOMXULLabelElement.h" +#include "nsIDOMXULSelectCntrlEl.h" +#include "nsIDOMXULSelectCntrlItemEl.h" +#include "nsReadableUtils.h" +#include "nsString.h" + +/** + * nsFormControlAccessible + */ + +nsFormControlAccessible::nsFormControlAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell): +nsAccessible(aNode, aShell) +{ +} + +/** + * XUL states: focused, unavailable(disabled), focusable, ?protected? + * HTML states: focused, unabailable(disabled), focusable, protected + */ +NS_IMETHODIMP nsFormControlAccessible::GetAccState(PRUint32 *_retval) +{ + // Get the focused state from the nsAccessible + nsAccessible::GetAccState(_retval); + + PRBool disabled = PR_FALSE; + nsresult rv = NS_ERROR_FAILURE; + nsCOMPtr htmlFormElement(do_QueryInterface(mDOMNode, &rv)); + if (NS_SUCCEEDED(rv) && htmlFormElement) { + htmlFormElement->GetDisabled(&disabled); + nsAutoString typeString; + htmlFormElement->GetType(typeString); + if (typeString.EqualsIgnoreCase("password")) + *_retval |= STATE_PROTECTED; + } + else { + nsCOMPtr xulFormElement(do_QueryInterface(mDOMNode, &rv)); + if (NS_SUCCEEDED(rv) && xulFormElement) { + xulFormElement->GetDisabled(&disabled); + /* XXX jgaunt do XUL elements support password fields? */ + } + } + if (disabled) + *_retval |= STATE_UNAVAILABLE; + else + *_retval |= STATE_FOCUSABLE; + + return NS_OK; +} + +/** + * Will be called by both HTML and XUL elements, this method + * merely checks who is calling and then calls the appropriate + * protected method for the XUL or HTML element. + */ +NS_IMETHODIMP nsFormControlAccessible::GetAccName(nsAWritableString& _retval) +{ + nsCOMPtr xulFormElement(do_QueryInterface(mDOMNode)); + if (xulFormElement) + return GetXULAccName(_retval); + else + return GetHTMLAccName(_retval); +} + +/** + * No Children + */ +NS_IMETHODIMP nsFormControlAccessible::GetAccFirstChild(nsIAccessible **_retval) +{ + *_retval = nsnull; + return NS_OK; +} + +/** + * No Children + */ +NS_IMETHODIMP nsFormControlAccessible::GetAccLastChild(nsIAccessible **_retval) +{ + *_retval = nsnull; + return NS_OK; +} + +/** + * No Children + */ +NS_IMETHODIMP nsFormControlAccessible::GetAccChildCount(PRInt32 *_retval) +{ + *_retval = 0; + return NS_OK; +} + +// ------------ +// Radio button +// ------------ + +nsRadioButtonAccessible::nsRadioButtonAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell): +nsFormControlAccessible(aNode, aShell) +{ +} + +/** + * + */ +NS_IMETHODIMP nsRadioButtonAccessible::GetAccNumActions(PRUint8 *_retval) +{ + *_retval = eSingle_Action; + return NS_OK; +} + +/** + * + */ +NS_IMETHODIMP nsRadioButtonAccessible::GetAccActionName(PRUint8 index, nsAWritableString& _retval) +{ + if (index == eAction_Click) { + _retval = NS_LITERAL_STRING("select"); + return NS_OK; + } + return NS_ERROR_INVALID_ARG; +} + +/** + * + */ +NS_IMETHODIMP nsRadioButtonAccessible::GetAccRole(PRUint32 *_retval) +{ + *_retval = ROLE_RADIOBUTTON; + + return NS_OK; +} + +// ------------ +// Text Accessibles +// ------------ + +nsTextAccessible::nsTextAccessible(nsIDOMNode* aDomNode, nsIWeakReference* aShell): +nsLinkableAccessible(aDomNode, aShell) +{ +} + +/** + * We are text + */ +NS_IMETHODIMP nsTextAccessible::GetAccRole(PRUint32 *_retval) +{ + *_retval = ROLE_TEXT; + + return NS_OK; +} + +/** + * No Children + */ +NS_IMETHODIMP nsTextAccessible::GetAccFirstChild(nsIAccessible **_retval) +{ + *_retval = nsnull; + return NS_OK; +} + +/** + * No Children + */ +NS_IMETHODIMP nsTextAccessible::GetAccLastChild(nsIAccessible **_retval) +{ + *_retval = nsnull; + return NS_OK; +} + +/** + * No Children + */ +NS_IMETHODIMP nsTextAccessible::GetAccChildCount(PRInt32 *_retval) +{ + *_retval = 0; + return NS_OK; +} + diff --git a/mozilla/accessible/src/nsHTMLListboxAccessible.h b/mozilla/accessible/src/base/nsFormControlAccessible.h similarity index 56% rename from mozilla/accessible/src/nsHTMLListboxAccessible.h rename to mozilla/accessible/src/base/nsFormControlAccessible.h index 08d323fb8e5..cd4ed5ff34a 100644 --- a/mozilla/accessible/src/nsHTMLListboxAccessible.h +++ b/mozilla/accessible/src/base/nsFormControlAccessible.h @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* ***** BEGIN LICENSE BLOCK ***** * Version: NPL 1.1/GPL 2.0/LGPL 2.1 * @@ -20,7 +20,7 @@ * the Initial Developer. All Rights Reserved. * * Contributor(s): - * Original Author: John Gaunt (jgaunt@netscape.com) + * Author: Eric D Vaughan (evaughan@netscape.com) * * * Alternatively, the contents of this file may be used under the terms of @@ -36,37 +36,58 @@ * the terms of any one of the NPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ -#ifndef __nsHTMLListboxAccessible_h__ -#define __nsHTMLListboxAccessible_h__ -#include "nsAccessible.h" -#include "nsIAccessibleSelectable.h" +#ifndef _nsFormControlAccessible_H_ +#define _nsFormControlAccessible_H_ -#include "nsCOMPtr.h" -#include "nsHTMLSelectListAccessible.h" +#include "nsBaseWidgetAccessible.h" -/* - * A class the represents the HTML Combobox widget. - */ -class nsHTMLListboxAccessible : public nsAccessible, - public nsIAccessibleSelectable +/** + * This supports name and state information for both XUL and HTML + * widgets. Designed to be a base class for the impls of XUL + * and HTML form widget Accessibles + */ +class nsFormControlAccessible : public nsAccessible { public: - - NS_DECL_ISUPPORTS_INHERITED - NS_DECL_NSIACCESSIBLESELECTABLE - - nsHTMLListboxAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell); - virtual ~nsHTMLListboxAccessible() {} - - /* ----- nsIAccessible ----- */ - NS_IMETHOD GetAccLastChild(nsIAccessible **_retval); + nsFormControlAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell); + NS_IMETHOD GetAccName(nsAWritableString& _retval); + NS_IMETHOD GetAccState(PRUint32 *_retval); NS_IMETHOD GetAccFirstChild(nsIAccessible **_retval); - NS_IMETHOD GetAccRole(PRUint32 *_retval); + NS_IMETHOD GetAccLastChild(nsIAccessible **_retval); NS_IMETHOD GetAccChildCount(PRInt32 *_retval); - NS_IMETHOD GetAccValue(nsAWritableString& _retval); - NS_IMETHOD GetAccState(PRUint32 *_retval); }; +/** + * + */ +class nsRadioButtonAccessible : public nsFormControlAccessible +{ + +public: + nsRadioButtonAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell); + NS_IMETHOD GetAccRole(PRUint32 *_retval); + NS_IMETHOD GetAccNumActions(PRUint8 *_retval); + NS_IMETHOD GetAccActionName(PRUint8 index, nsAWritableString& _retval); +}; + +/** + * Text nodes have no children, but since double inheritance + * no-worky we have to re-impl the LeafAccessiblity blocks + * this way. + */ +class nsTextAccessible : public nsLinkableAccessible +{ + +public: + nsTextAccessible(nsIDOMNode* aDomNode, nsIWeakReference* aShell); + NS_IMETHOD GetAccRole(PRUint32 *_retval); + NS_IMETHOD GetAccFirstChild(nsIAccessible **_retval); + NS_IMETHOD GetAccLastChild(nsIAccessible **_retval); + NS_IMETHOD GetAccChildCount(PRInt32 *_retval); +}; + + #endif + diff --git a/mozilla/accessible/src/base/nsRootAccessible.cpp b/mozilla/accessible/src/base/nsRootAccessible.cpp index a7e4c462302..f5c441e1b98 100644 --- a/mozilla/accessible/src/base/nsRootAccessible.cpp +++ b/mozilla/accessible/src/base/nsRootAccessible.cpp @@ -68,7 +68,7 @@ #include "nsXPIDLString.h" #include "nsIAccessibilityService.h" #include "nsIServiceManager.h" -#include "nsHTMLSelectListAccessible.h" +#include "nsHTMLSelectAccessible.h" #include "nsIDOMHTMLSelectElement.h" #include "nsIWebProgress.h" #include "nsCURILoader.h" diff --git a/mozilla/accessible/src/base/nsRootAccessible.h b/mozilla/accessible/src/base/nsRootAccessible.h index f194b938cdd..e3326ebf5f0 100644 --- a/mozilla/accessible/src/base/nsRootAccessible.h +++ b/mozilla/accessible/src/base/nsRootAccessible.h @@ -96,7 +96,6 @@ class nsRootAccessible : public nsAccessible, NS_IMETHOD GetAccState(PRUint32 *aAccState); // ----- nsIAccessibleEventReceiver ------------------- - NS_IMETHOD AddAccessibleEventListener(nsIAccessibleEventListener *aListener); NS_IMETHOD RemoveAccessibleEventListener(); diff --git a/mozilla/accessible/src/nsHTMLComboboxAccessible.cpp b/mozilla/accessible/src/base/nsSelectAccessible.cpp similarity index 54% rename from mozilla/accessible/src/nsHTMLComboboxAccessible.cpp rename to mozilla/accessible/src/base/nsSelectAccessible.cpp index 5157eff97db..1653617a817 100644 --- a/mozilla/accessible/src/nsHTMLComboboxAccessible.cpp +++ b/mozilla/accessible/src/base/nsSelectAccessible.cpp @@ -38,25 +38,172 @@ * * ***** END LICENSE BLOCK ***** */ -#include "nsHTMLComboboxAccessible.h" - #include "nsCOMPtr.h" +#include "nsFormControlAccessible.h" +#include "nsIAtom.h" #include "nsIComboboxControlFrame.h" #include "nsIDOMEventReceiver.h" -#include "nsIDOMHTMLInputElement.h" +#include "nsIDOMHTMLCollection.h" +#include "nsIDOMHTMLOptionElement.h" #include "nsIDOMHTMLSelectElement.h" #include "nsIFrame.h" +#include "nsIListControlFrame.h" +#include "nsISelectControlFrame.h" #include "nsLayoutAtoms.h" +#include "nsRootAccessible.h" +#include "nsSelectAccessible.h" -/** ----- nsHTMLComboboxAccessible ----- */ +/** ------------------------------------------------------ */ +/** First, the common widgets */ +/** ------------------------------------------------------ */ + +/** Constructor -- cache our parent */ +nsSelectListAccessible::nsSelectListAccessible(nsIAccessible* aParent, + nsIDOMNode* aDOMNode, + nsIWeakReference* aShell) +:nsAccessible(aDOMNode, aShell) +{ + mParent = aParent; +} + +/** Return our parents bounds */ +NS_IMETHODIMP nsSelectListAccessible::AccGetBounds(PRInt32 *x, PRInt32 *y, PRInt32 *width, PRInt32 *height) +{ + return mParent->AccGetBounds(x,y,width,height); +} + +/** Return our cached parent */ +NS_IMETHODIMP nsSelectListAccessible::GetAccParent(nsIAccessible **_retval) +{ + *_retval = mParent; + NS_ADDREF(*_retval); + return NS_OK; +} + +/** We are a list */ +NS_IMETHODIMP nsSelectListAccessible::GetAccRole(PRUint32 *_retval) +{ + *_retval = ROLE_LIST; + return NS_OK; +} + +/** We are an only child */ +NS_IMETHODIMP nsSelectListAccessible::GetAccPreviousSibling(nsIAccessible **_retval) +{ + *_retval = nsnull; + return NS_OK; +} + +/** We are an only child */ +NS_IMETHODIMP nsSelectListAccessible::GetAccNextSibling(nsIAccessible **_retval) +{ + *_retval = nsnull; + return NS_OK; +} /** - * Constructor -- create the nsHTMLAccessible and set initial state - * closed and not registered + * nsSelectOptionAccessible */ -nsHTMLComboboxAccessible::nsHTMLComboboxAccessible(nsIDOMNode* aDOMNode, - nsIWeakReference* aShell) - :nsAccessible(aDOMNode, aShell) + +/** Constructor -- cache our parent */ +nsSelectOptionAccessible::nsSelectOptionAccessible(nsIAccessible* aParent, nsIDOMNode* aDOMNode, nsIWeakReference* aShell): +nsLeafAccessible(aDOMNode, aShell) +{ + mParent = aParent; +} + +/** We are a ListItem */ +NS_IMETHODIMP nsSelectOptionAccessible::GetAccRole(PRUint32 *_retval) +{ + *_retval = ROLE_LISTITEM; + return NS_OK; +} + +/** Return our cached parent */ +NS_IMETHODIMP nsSelectOptionAccessible::GetAccParent(nsIAccessible **_retval) +{ + *_retval = mParent; + NS_IF_ADDREF(*_retval); + return NS_OK; +} + +/** + * Get our Name from our Content's subtree + */ +NS_IMETHODIMP nsSelectOptionAccessible::GetAccName(nsAWritableString& _retval) +{ + nsCOMPtr content (do_QueryInterface(mDOMNode)); + if (!content) { + return NS_ERROR_FAILURE; + } + + nsAutoString option; + nsresult rv = AppendFlatStringFromSubtree(content, &option); + if (NS_SUCCEEDED(rv)) { + // Temp var needed until CompressWhitespace built for nsAWritableString + option.CompressWhitespace(); + _retval.Assign(option); + } + return rv; +} + +/** ------------------------------------------------------ */ +/** Secondly, the Listbox widget */ +/** ------------------------------------------------------ */ + +/** ----- nsListboxAccessible ----- */ + +/** Constructor */ +nsListboxAccessible::nsListboxAccessible(nsIDOMNode* aDOMNode, + nsIWeakReference* aShell): +nsAccessible(aDOMNode, aShell) +{ +} + +/** 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; +} + +/** ------------------------------------------------------ */ +/** 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; @@ -66,7 +213,7 @@ nsHTMLComboboxAccessible::nsHTMLComboboxAccessible(nsIDOMNode* aDOMNode, /** * Destructor -- If we are registered, remove ourselves as a listener. */ -nsHTMLComboboxAccessible::~nsHTMLComboboxAccessible() +nsComboboxAccessible::~nsComboboxAccessible() { if (mRegistered) { nsCOMPtr eventReceiver(do_QueryInterface(mDOMNode)); @@ -75,46 +222,40 @@ nsHTMLComboboxAccessible::~nsHTMLComboboxAccessible() } } -/** Inherit the ISupports impl from nsAccessible -- handle nsIDOMXULListener ourself */ -NS_IMPL_ISUPPORTS_INHERITED1(nsHTMLComboboxAccessible, nsAccessible, nsIDOMXULListener) - /** - * Tell our caller we are a combobox + * Inherit the ISupports impl from nsAccessible, + * handle nsIDOMXULListener and nsIAccessibleSelectable ourself */ -NS_IMETHODIMP nsHTMLComboboxAccessible::GetAccRole(PRUint32 *_retval) +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; } -/** - * Through the arg, pass back our last child, a nsHTMLComboboxWindowAccessible object - */ -NS_IMETHODIMP nsHTMLComboboxAccessible::GetAccLastChild(nsIAccessible **_retval) -{ - *_retval = new nsHTMLComboboxWindowAccessible(this, mDOMNode, mPresShell); - if (! *_retval) - return NS_ERROR_FAILURE; - NS_ADDREF(*_retval); - return NS_OK; -} - -/** - * Through the arg, pass back our first child, a nsHTMLComboboxTextFieldAccessible object - */ -NS_IMETHODIMP nsHTMLComboboxAccessible::GetAccFirstChild(nsIAccessible **_retval) -{ - *_retval = new nsHTMLComboboxTextFieldAccessible(this, mDOMNode, mPresShell); - if (! *_retval) - return NS_ERROR_FAILURE; - NS_ADDREF(*_retval); - return NS_OK; -} - /** * We always have 3 children: TextField, Button, Window. In that order */ -NS_IMETHODIMP nsHTMLComboboxAccessible::GetAccChildCount(PRInt32 *_retval) +NS_IMETHODIMP nsComboboxAccessible::GetAccChildCount(PRInt32 *_retval) { *_retval = 3; return NS_OK; @@ -123,30 +264,17 @@ NS_IMETHODIMP nsHTMLComboboxAccessible::GetAccChildCount(PRInt32 *_retval) /** * 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. + * and another option for them to get at stuff. Despite the fact that we are + * single selection only. */ -NS_IMETHODIMP nsHTMLComboboxAccessible::GetSelectedChildren(nsISupportsArray **_retval) +NS_IMETHODIMP nsComboboxAccessible::GetSelectedChildren(nsISupportsArray **_retval) { *_retval = nsnull; return NS_OK; } /** - * Our value is the value of our ( first ) selected child. SelectElement - * returns this by default with GetValue(). - */ -NS_IMETHODIMP nsHTMLComboboxAccessible::GetAccValue(nsAWritableString& _retval) -{ - nsCOMPtr select (do_QueryInterface(mDOMNode)); - if (select) { - select->GetValue(_retval); - return NS_OK; - } - return NS_ERROR_FAILURE; -} - -/** - * As a nsHTMLComboboxAccessible we can have the following states: + * As a nsComboboxAccessible we can have the following states: * STATE_FOCUSED * STATE_READONLY * STATE_FOCUSABLE @@ -154,9 +282,9 @@ NS_IMETHODIMP nsHTMLComboboxAccessible::GetAccValue(nsAWritableString& _retval) * STATE_EXPANDED * STATE_COLLAPSED */ -NS_IMETHODIMP nsHTMLComboboxAccessible::GetAccState(PRUint32 *_retval) +NS_IMETHODIMP nsComboboxAccessible::GetAccState(PRUint32 *_retval) { - // this sets either STATE_FOCUSED or 0 + // Get focus status from base class nsAccessible::GetAccState(_retval); if (mOpen) @@ -173,7 +301,7 @@ NS_IMETHODIMP nsHTMLComboboxAccessible::GetAccState(PRUint32 *_retval) * Set our state to open and (TBD) fire an event to MSAA saying our state * has changed. */ -NS_IMETHODIMP nsHTMLComboboxAccessible::PopupShowing(nsIDOMEvent* aEvent) +NS_IMETHODIMP nsComboboxAccessible::PopupShowing(nsIDOMEvent* aEvent) { mOpen = PR_TRUE; @@ -186,7 +314,7 @@ NS_IMETHODIMP nsHTMLComboboxAccessible::PopupShowing(nsIDOMEvent* aEvent) * Set our state to not open and (TDB) fire an event to MSAA saying * our state has changed. */ -NS_IMETHODIMP nsHTMLComboboxAccessible::PopupHiding(nsIDOMEvent* aEvent) +NS_IMETHODIMP nsComboboxAccessible::PopupHiding(nsIDOMEvent* aEvent) { mOpen = PR_FALSE; @@ -199,7 +327,7 @@ NS_IMETHODIMP nsHTMLComboboxAccessible::PopupHiding(nsIDOMEvent* aEvent) * Set our state to not open and (TDB) fire an event to MSAA saying * our state has changed. */ -NS_IMETHODIMP nsHTMLComboboxAccessible::Close(nsIDOMEvent* aEvent) +NS_IMETHODIMP nsComboboxAccessible::Close(nsIDOMEvent* aEvent) { mOpen = PR_FALSE; @@ -208,33 +336,13 @@ NS_IMETHODIMP nsHTMLComboboxAccessible::Close(nsIDOMEvent* aEvent) return NS_OK; } -/** - * 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 -nsHTMLComboboxAccessible::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; - } -} +/** ----- nsComboboxTextFieldAccessible ----- */ - -/** ----- nsHTMLComboboxTextFieldAccessible ----- */ - -/** - * Constructor -- create the nsLeafAccessible and set our parent - */ -nsHTMLComboboxTextFieldAccessible::nsHTMLComboboxTextFieldAccessible(nsIAccessible* aParent, +/** Constructor */ +nsComboboxTextFieldAccessible::nsComboboxTextFieldAccessible(nsIAccessible* aParent, nsIDOMNode* aDOMNode, - nsIWeakReference* aShell) - :nsLeafAccessible(aDOMNode, aShell) + nsIWeakReference* aShell): +nsLeafAccessible(aDOMNode, aShell) { mParent = aParent; } @@ -244,7 +352,7 @@ nsHTMLComboboxTextFieldAccessible::nsHTMLComboboxTextFieldAccessible(nsIAccessib * and then return that text. * Walks the Frame tree and checks for proper frames. */ -NS_IMETHODIMP nsHTMLComboboxTextFieldAccessible::GetAccValue(nsAWritableString& _retval) +NS_IMETHODIMP nsComboboxTextFieldAccessible::GetAccValue(nsAWritableString& _retval) { nsIFrame* frame = nsAccessible::GetBoundsFrame(); nsCOMPtr context; @@ -279,7 +387,7 @@ NS_IMETHODIMP nsHTMLComboboxTextFieldAccessible::GetAccValue(nsAWritableString& * Gets the bounds for the BlockFrame. * Walks the Frame tree and checks for proper frames. */ -void nsHTMLComboboxTextFieldAccessible::GetBounds(nsRect& aBounds, nsIFrame** aBoundingFrame) +void nsComboboxTextFieldAccessible::GetBounds(nsRect& aBounds, nsIFrame** aBoundingFrame) { // get our first child's frame nsIFrame* frame = nsAccessible::GetBoundsFrame(); @@ -298,36 +406,18 @@ void nsHTMLComboboxTextFieldAccessible::GetBounds(nsRect& aBounds, nsIFrame** aB frame->GetRect(aBounds); } -/** - * Getter for our parent - */ -NS_IMETHODIMP nsHTMLComboboxTextFieldAccessible::GetAccParent(nsIAccessible **_retval) +/** Return our cached parent */ +NS_IMETHODIMP nsComboboxTextFieldAccessible::GetAccParent(nsIAccessible **_retval) { *_retval = mParent; NS_IF_ADDREF(*_retval); return NS_OK; } -/** - * Through the arg, pass back our next sibling, a - * nsHTMLComboboxButtonAccessible object - */ -NS_IMETHODIMP nsHTMLComboboxTextFieldAccessible::GetAccNextSibling(nsIAccessible **_retval) -{ - nsCOMPtr parent; - GetAccParent(getter_AddRefs(parent)); - - *_retval = new nsHTMLComboboxButtonAccessible(parent, mDOMNode, mPresShell); - if (! *_retval) - return NS_ERROR_FAILURE; - NS_ADDREF(*_retval); - return NS_OK; -} - /** * We are the first child of our parent, no previous sibling */ -NS_IMETHODIMP nsHTMLComboboxTextFieldAccessible::GetAccPreviousSibling(nsIAccessible **_retval) +NS_IMETHODIMP nsComboboxTextFieldAccessible::GetAccPreviousSibling(nsIAccessible **_retval) { *_retval = nsnull; return NS_OK; @@ -337,21 +427,21 @@ NS_IMETHODIMP nsHTMLComboboxTextFieldAccessible::GetAccPreviousSibling(nsIAccess * Our role is currently only static text, but we should be able to have * editable text here and we need to check that case. */ -NS_IMETHODIMP nsHTMLComboboxTextFieldAccessible::GetAccRole(PRUint32 *_retval) +NS_IMETHODIMP nsComboboxTextFieldAccessible::GetAccRole(PRUint32 *_retval) { *_retval = ROLE_STATICTEXT; return NS_OK; } /** - * As a nsHTMLComboboxTextFieldAccessible we can have the following states: + * As a nsComboboxTextFieldAccessible we can have the following states: * STATE_READONLY * STATE_FOCUSED * STATE_FOCUSABLE */ -NS_IMETHODIMP nsHTMLComboboxTextFieldAccessible::GetAccState(PRUint32 *_retval) +NS_IMETHODIMP nsComboboxTextFieldAccessible::GetAccState(PRUint32 *_retval) { - // this sets either STATE_FOCUSED or 0 + // Get focus status from base class nsAccessible::GetAccState(_retval); *_retval |= STATE_READONLY | STATE_FOCUSABLE; @@ -359,68 +449,21 @@ NS_IMETHODIMP nsHTMLComboboxTextFieldAccessible::GetAccState(PRUint32 *_retval) return NS_OK; } +/** -----ComboboxButtonAccessible ----- */ -/** -----SelectButtonAccessible ----- */ - -/** - * Constructor -- create the nsMenuListenerAccessible and set our parent - */ -nsHTMLComboboxButtonAccessible::nsHTMLComboboxButtonAccessible(nsIAccessible* aParent, +/** Constructor -- cache our parent */ +nsComboboxButtonAccessible::nsComboboxButtonAccessible(nsIAccessible* aParent, nsIDOMNode* aDOMNode, - nsIWeakReference* aShell) - :nsAccessible(aDOMNode, aShell) + nsIWeakReference* aShell): +nsLeafAccessible(aDOMNode, aShell) { mParent = aParent; } -/** - * Programmaticaly click on the button, causing either the display or - * the hiding of the drop down box ( window ). - * Walks the Frame tree and checks for proper frames. - */ -NS_IMETHODIMP nsHTMLComboboxButtonAccessible::AccDoAction(PRUint8 index) +/** Just one action ( click ). */ +NS_IMETHODIMP nsComboboxButtonAccessible::GetAccNumActions(PRUint8 *_retval) { - nsIFrame* frame = nsAccessible::GetBoundsFrame(); - nsCOMPtr context; - GetPresContext(context); - if (!context) - return NS_ERROR_FAILURE; - - frame->FirstChild(context, nsnull, &frame); -#ifdef DEBUG - if (! nsAccessible::IsCorrectFrameType(frame, nsLayoutAtoms::blockFrame)) - return NS_ERROR_FAILURE; -#endif - - frame->GetNextSibling(&frame); -#ifdef DEBUG - if (! nsAccessible::IsCorrectFrameType(frame, nsLayoutAtoms::gfxButtonControlFrame)) - return NS_ERROR_FAILURE; -#endif - - nsCOMPtr content; - frame->GetContent(getter_AddRefs(content)); - - // We only have one action, click. Any other index is meaningless(wrong) - if (index == eAction_Click) { - nsCOMPtr element(do_QueryInterface(content)); - if (element) - { - element->Click(); - return NS_OK; - } - return NS_ERROR_FAILURE; - } - return NS_ERROR_INVALID_ARG; -} - - -/** - * Just one action ( click ). - */ -NS_IMETHODIMP nsHTMLComboboxButtonAccessible::GetAccNumActions(PRUint8 *_retval) -{ - *_retval = 1; + *_retval = eSingle_Action; return NS_OK; } @@ -428,7 +471,7 @@ NS_IMETHODIMP nsHTMLComboboxButtonAccessible::GetAccNumActions(PRUint8 *_retval) * Gets the bounds for the gfxButtonControlFrame. * Walks the Frame tree and checks for proper frames. */ -void nsHTMLComboboxButtonAccessible::GetBounds(nsRect& aBounds, nsIFrame** aBoundingFrame) +void nsComboboxButtonAccessible::GetBounds(nsRect& aBounds, nsIFrame** aBoundingFrame) { // get our second child's frame nsIFrame* frame = nsAccessible::GetBoundsFrame(); @@ -453,29 +496,25 @@ void nsHTMLComboboxButtonAccessible::GetBounds(nsRect& aBounds, nsIFrame** aBoun frame->GetRect(aBounds); } -/** - * Tell our caller we are a button. - */ -NS_IMETHODIMP nsHTMLComboboxButtonAccessible::GetAccRole(PRUint32 *_retval) +/** We are a button. */ +NS_IMETHODIMP nsComboboxButtonAccessible::GetAccRole(PRUint32 *_retval) { *_retval = ROLE_PUSHBUTTON; return NS_OK; } -/** - * Getter for our parent - */ -NS_IMETHODIMP nsHTMLComboboxButtonAccessible::GetAccParent(nsIAccessible **_retval) +/** Return our cached parent */ +NS_IMETHODIMP nsComboboxButtonAccessible::GetAccParent(nsIAccessible **_retval) { *_retval = mParent; NS_IF_ADDREF(*_retval); return NS_OK; } -/** +/** * Gets the name from GetAccActionName() */ -NS_IMETHODIMP nsHTMLComboboxButtonAccessible::GetAccName(nsAWritableString& _retval) +NS_IMETHODIMP nsComboboxButtonAccessible::GetAccName(nsAWritableString& _retval) { return GetAccActionName(eAction_Click, _retval); } @@ -484,10 +523,10 @@ NS_IMETHODIMP nsHTMLComboboxButtonAccessible::GetAccName(nsAWritableString& _ret * Our action name is the reverse of our state: * if we are closed -> open is our name. * if we are open -> closed is our name. + * Uses the frame to get the state, updated on every click */ -NS_IMETHODIMP nsHTMLComboboxButtonAccessible::GetAccActionName(PRUint8 index, nsAWritableString& _retval) +NS_IMETHODIMP nsComboboxButtonAccessible::GetAccActionName(PRUint8 index, nsAWritableString& _retval) { - // we are open or closed PRBool isOpen = PR_FALSE; nsIFrame *boundsFrame = GetBoundsFrame(); nsIComboboxControlFrame* comboFrame; @@ -504,76 +543,17 @@ NS_IMETHODIMP nsHTMLComboboxButtonAccessible::GetAccActionName(PRUint8 index, ns } /** - * Through the arg, pass back our next sibling, a - * nsHTMLComboboxWindowAccessible object - */ -NS_IMETHODIMP nsHTMLComboboxButtonAccessible::GetAccNextSibling(nsIAccessible **_retval) -{ - nsCOMPtr parent; - GetAccParent(getter_AddRefs(parent)); - - *_retval = new nsHTMLComboboxWindowAccessible(parent, mDOMNode, mPresShell); - if (! *_retval) - return NS_ERROR_OUT_OF_MEMORY; - NS_ADDREF(*_retval); - return NS_OK; -} - -/** - * Through the arg, pass back our previous sibling, a - * nsHTMLComboboxTextFieldAccessible object - */ -NS_IMETHODIMP nsHTMLComboboxButtonAccessible::GetAccPreviousSibling(nsIAccessible **_retval) -{ - nsCOMPtr parent; - GetAccParent(getter_AddRefs(parent)); - - *_retval = new nsHTMLComboboxTextFieldAccessible(parent, mDOMNode, mPresShell); - if (! *_retval) - return NS_ERROR_FAILURE; - NS_ADDREF(*_retval); - return NS_OK; -} - -/** - * No Children. Just a button ( over-riding nsAccessible ) - */ -NS_IMETHODIMP nsHTMLComboboxButtonAccessible::GetAccLastChild(nsIAccessible **_retval) -{ - *_retval = nsnull; - return NS_OK; -} - -/** - * No Children. Just a button ( over-riding nsAccessible ) - */ -NS_IMETHODIMP nsHTMLComboboxButtonAccessible::GetAccFirstChild(nsIAccessible **_retval) -{ - *_retval = nsnull; - return NS_OK; -} - -/** - * No Children. Just a button ( over-riding nsAccessible ) - */ -NS_IMETHODIMP nsHTMLComboboxButtonAccessible::GetAccChildCount(PRInt32 *_retval) -{ - *_retval = 0; - return NS_OK; -} - -/** - * As a nsHTMLComboboxButtonAccessible we can have the following states: + * As a nsComboboxButtonAccessible we can have the following states: * STATE_PRESSED * STATE_FOCUSED * STATE_FOCUSABLE */ -NS_IMETHODIMP nsHTMLComboboxButtonAccessible::GetAccState(PRUint32 *_retval) +NS_IMETHODIMP nsComboboxButtonAccessible::GetAccState(PRUint32 *_retval) { - // this sets either STATE_FOCUSED or 0 + // Get focus status from base class nsAccessible::GetAccState(_retval); - // we are open or closed + // we are open or closed --> pressed or not PRBool isOpen = PR_FALSE; nsIFrame *boundsFrame = GetBoundsFrame(); nsIComboboxControlFrame* comboFrame; @@ -589,30 +569,29 @@ NS_IMETHODIMP nsHTMLComboboxButtonAccessible::GetAccState(PRUint32 *_retval) return NS_OK; } - -/** ----- nsHTMLComboboxWindowAccessible ----- */ +/** ----- nsComboboxWindowAccessible ----- */ /** - * Constructor -- create the nsMenuListener and set our parent + * Constructor -- cache our parent */ -nsHTMLComboboxWindowAccessible::nsHTMLComboboxWindowAccessible(nsIAccessible* aParent, +nsComboboxWindowAccessible::nsComboboxWindowAccessible(nsIAccessible* aParent, nsIDOMNode* aDOMNode, - nsIWeakReference* aShell) - :nsAccessible(aDOMNode, aShell) + nsIWeakReference* aShell): +nsAccessible(aDOMNode, aShell) { mParent = aParent; } /** - * As a nsHTMLComboboxWindowAccessible we can have the following states: + * As a nsComboboxWindowAccessible we can have the following states: * STATE_FOCUSED * STATE_FOCUSABLE * STATE_INVISIBLE * STATE_FLOATING */ -NS_IMETHODIMP nsHTMLComboboxWindowAccessible::GetAccState(PRUint32 *_retval) +NS_IMETHODIMP nsComboboxWindowAccessible::GetAccState(PRUint32 *_retval) { - // this sets either STATE_FOCUSED or 0 + // Get focus status from base class nsAccessible::GetAccState(_retval); // we are open or closed @@ -631,45 +610,25 @@ NS_IMETHODIMP nsHTMLComboboxWindowAccessible::GetAccState(PRUint32 *_retval) return NS_OK; } -/** - * Tell our caller we are a window - */ -NS_IMETHODIMP nsHTMLComboboxWindowAccessible::GetAccRole(PRUint32 *_retval) +/** We are a window */ +NS_IMETHODIMP nsComboboxWindowAccessible::GetAccRole(PRUint32 *_retval) { *_retval = ROLE_WINDOW; return NS_OK; } -/** - * Getter for our parent - */ -NS_IMETHODIMP nsHTMLComboboxWindowAccessible::GetAccParent(nsIAccessible **_retval) +/** Return our cached parent */ +NS_IMETHODIMP nsComboboxWindowAccessible::GetAccParent(nsIAccessible **_retval) { *_retval = mParent; NS_IF_ADDREF(*_retval); return NS_OK; } - -/** - * Through the arg, pass back our previous sibling, a - * nsHTMLComboboxButtonAccessible object - */ -NS_IMETHODIMP nsHTMLComboboxWindowAccessible::GetAccPreviousSibling(nsIAccessible **_retval) -{ - nsCOMPtr parent; - GetAccParent(getter_AddRefs(parent)); - - *_retval = new nsHTMLComboboxButtonAccessible(parent, mDOMNode, mPresShell); - if (! *_retval) - return NS_ERROR_FAILURE; - NS_ADDREF(*_retval); - return NS_OK; -} /** * We are the last sibling of our parent. */ -NS_IMETHODIMP nsHTMLComboboxWindowAccessible::GetAccNextSibling(nsIAccessible **_retval) +NS_IMETHODIMP nsComboboxWindowAccessible::GetAccNextSibling(nsIAccessible **_retval) { *_retval = nsnull; return NS_OK; @@ -678,31 +637,7 @@ NS_IMETHODIMP nsHTMLComboboxWindowAccessible::GetAccNextSibling(nsIAccessible ** /** * We only have one child, a list */ -NS_IMETHODIMP nsHTMLComboboxWindowAccessible::GetAccLastChild(nsIAccessible **_retval) -{ - *_retval = new nsHTMLSelectListAccessible(this, mDOMNode, mPresShell); - if (! *_retval) - return NS_ERROR_FAILURE; - NS_ADDREF(*_retval); - return NS_OK; -} - -/** - * We only have one child, a list - */ -NS_IMETHODIMP nsHTMLComboboxWindowAccessible::GetAccFirstChild(nsIAccessible **_retval) -{ - *_retval = new nsHTMLSelectListAccessible(this, mDOMNode, mPresShell); - if (! *_retval) - return NS_ERROR_FAILURE; - NS_ADDREF(*_retval); - return NS_OK; -} - -/** - * We only have one child, a list - */ -NS_IMETHODIMP nsHTMLComboboxWindowAccessible::GetAccChildCount(PRInt32 *_retval) +NS_IMETHODIMP nsComboboxWindowAccessible::GetAccChildCount(PRInt32 *_retval) { *_retval = 1; return NS_OK; @@ -712,7 +647,7 @@ NS_IMETHODIMP nsHTMLComboboxWindowAccessible::GetAccChildCount(PRInt32 *_retval) * Gets the bounds for the areaFrame. * Walks the Frame tree and checks for proper frames. */ -void nsHTMLComboboxWindowAccessible::GetBounds(nsRect& aBounds, nsIFrame** aBoundingFrame) +void nsComboboxWindowAccessible::GetBounds(nsRect& aBounds, nsIFrame** aBoundingFrame) { // get our first option nsCOMPtr child; @@ -742,3 +677,4 @@ void nsHTMLComboboxWindowAccessible::GetBounds(nsRect& aBounds, nsIFrame** aBoun frame->GetRect(aBounds); } + diff --git a/mozilla/accessible/src/nsHTMLComboboxAccessible.h b/mozilla/accessible/src/base/nsSelectAccessible.h similarity index 56% rename from mozilla/accessible/src/nsHTMLComboboxAccessible.h rename to mozilla/accessible/src/base/nsSelectAccessible.h index 9592eb65c4b..58e44bd892c 100644 --- a/mozilla/accessible/src/nsHTMLComboboxAccessible.h +++ b/mozilla/accessible/src/base/nsSelectAccessible.h @@ -20,7 +20,8 @@ * the Initial Developer. All Rights Reserved. * * Contributor(s): - * Original Author: John Gaunt (jgaunt@netscape.com) + * Original Author: Eric Vaughan (evaughan@netscape.com) + * Contributor(s): John Gaunt (jgaunt@netscape.com) * * * Alternatively, the contents of this file may be used under the terms of @@ -36,41 +37,106 @@ * the terms of any one of the NPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ -#ifndef __nsHTMLComboboxAccessible_h__ -#define __nsHTMLComboboxAccessible_h__ -#include "nsAccessible.h" +#ifndef __nsSelectAccessible_h__ +#define __nsSelectAccessible_h__ + #include "nsBaseWidgetAccessible.h" #include "nsIAccessibleSelectable.h" - -#include "nsCOMPtr.h" -#include "nsHTMLSelectListAccessible.h" #include "nsIDOMXULListener.h" -/* - * A class the represents the HTML Combobox widget. - */ -class nsHTMLComboboxAccessible : public nsAccessible, - public nsIAccessibleSelectable, - public nsIDOMXULListener +/** ------------------------------------------------------ */ +/** First, the common widgets */ +/** ------------------------------------------------------ */ + +/** + * The list that contains all the options in the select. + */ +class nsSelectListAccessible : public nsAccessible +{ +public: + + nsSelectListAccessible(nsIAccessible* aParent, nsIDOMNode* aDOMNode, nsIWeakReference* aShell); + virtual ~nsSelectListAccessible() {} + + /* ----- nsIAccessible ----- */ + NS_IMETHOD GetAccParent(nsIAccessible **_retval); + NS_IMETHOD GetAccRole(PRUint32 *_retval); + NS_IMETHOD AccGetBounds(PRInt32 *x, PRInt32 *y, PRInt32 *width, PRInt32 *height); + NS_IMETHOD GetAccNextSibling(nsIAccessible **_retval); + NS_IMETHOD GetAccPreviousSibling(nsIAccessible **_retval); + +protected: + + nsCOMPtr mParent; +}; + +/** + * Options inside the select, contained within the list + */ +class nsSelectOptionAccessible : public nsLeafAccessible +{ +public: + + nsSelectOptionAccessible(nsIAccessible* aParent, nsIDOMNode* aDOMNode, nsIWeakReference* aShell); + virtual ~nsSelectOptionAccessible() {} + + /* ----- nsIAccessible ----- */ + NS_IMETHOD GetAccParent(nsIAccessible **_retval); + NS_IMETHOD GetAccRole(PRUint32 *_retval); + NS_IMETHOD GetAccName(nsAWritableString& _retval); + +protected: + + nsCOMPtr mParent; +}; + +/** ------------------------------------------------------ */ +/** Secondly, the Listbox widget */ +/** ------------------------------------------------------ */ + +/** + * A class that represents the Listbox widget. + */ +class nsListboxAccessible : public nsAccessible +{ +public: + + 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 - nsHTMLComboboxAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell); - virtual ~nsHTMLComboboxAccessible(); + nsComboboxAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell); + virtual ~nsComboboxAccessible(); /* ----- nsIAccessible ----- */ - NS_IMETHOD GetAccLastChild(nsIAccessible **_retval); - NS_IMETHOD GetAccFirstChild(nsIAccessible **_retval); NS_IMETHOD GetAccRole(PRUint32 *_retval); NS_IMETHOD GetAccChildCount(PRInt32 *_retval); - NS_IMETHOD GetAccValue(nsAWritableString& _retval); NS_IMETHOD GetAccState(PRUint32 *_retval); - // popup listener + /* ----- nsIDOMXULListener ----- */ NS_IMETHOD PopupShowing(nsIDOMEvent* aEvent); NS_IMETHOD PopupShown(nsIDOMEvent* aEvent) { return NS_OK; } NS_IMETHOD PopupHiding(nsIDOMEvent* aEvent); @@ -91,18 +157,18 @@ protected: }; -/* - * A class the represents the text field in the Select to the left - * of the drop down button - */ -class nsHTMLComboboxTextFieldAccessible : public nsLeafAccessible +/** + * A class the represents the text field in the Combobox to the left + * of the drop down button + */ +class nsComboboxTextFieldAccessible : public nsLeafAccessible { public: - nsHTMLComboboxTextFieldAccessible(nsIAccessible* aParent, nsIDOMNode* aDOMNode, nsIWeakReference* aShell); + nsComboboxTextFieldAccessible(nsIAccessible* aParent, nsIDOMNode* aDOMNode, nsIWeakReference* aShell); + virtual ~nsComboboxTextFieldAccessible() {} /* ----- nsIAccessible ----- */ - NS_IMETHOD GetAccNextSibling(nsIAccessible **_retval); NS_IMETHOD GetAccPreviousSibling(nsIAccessible **_retval); NS_IMETHOD GetAccParent(nsIAccessible **_retval); NS_IMETHOD GetAccRole(PRUint32 *_retval); @@ -120,26 +186,19 @@ protected: * A class that represents the button inside the Select to the * right of the text field */ -class nsHTMLComboboxButtonAccessible : public nsAccessible +class nsComboboxButtonAccessible : public nsLeafAccessible { public: - enum { eAction_Click=0 }; - - nsHTMLComboboxButtonAccessible(nsIAccessible* aParent, nsIDOMNode* aDOMNode, nsIWeakReference* aShell); + nsComboboxButtonAccessible(nsIAccessible* aParent, nsIDOMNode* aDOMNode, nsIWeakReference* aShell); + virtual ~nsComboboxButtonAccessible() {} /* ----- nsIAccessible ----- */ - NS_IMETHOD GetAccNextSibling(nsIAccessible **_retval); - NS_IMETHOD GetAccPreviousSibling(nsIAccessible **_retval); NS_IMETHOD GetAccParent(nsIAccessible **_retval); NS_IMETHOD GetAccName(nsAWritableString& _retval); NS_IMETHOD GetAccRole(PRUint32 *_retval); - NS_IMETHOD GetAccLastChild(nsIAccessible **_retval); - NS_IMETHOD GetAccFirstChild(nsIAccessible **_retval); - NS_IMETHOD GetAccChildCount(PRInt32 *_retval); NS_IMETHOD GetAccNumActions(PRUint8 *_retval); NS_IMETHOD GetAccActionName(PRUint8 index, nsAWritableString& _retval); - NS_IMETHOD AccDoAction(PRUint8 index); NS_IMETHOD GetAccState(PRUint32 *_retval); virtual void GetBounds(nsRect& aBounds, nsIFrame** aBoundingFrame); @@ -149,23 +208,21 @@ protected: nsCOMPtr mParent; }; -/* - * A class that represents the window that lives to the right - * of the drop down button inside the Select. This is the window - * that is made visible when the button is pressed. - */ -class nsHTMLComboboxWindowAccessible : public nsAccessible +/** + * A class that represents the window that lives to the right + * of the drop down button inside the Select. This is the window + * that is made visible when the button is pressed. + */ +class nsComboboxWindowAccessible : public nsAccessible { public: - nsHTMLComboboxWindowAccessible(nsIAccessible* aParent, nsIDOMNode* aDOMNode, nsIWeakReference* aShell); + nsComboboxWindowAccessible(nsIAccessible* aParent, nsIDOMNode* aDOMNode, nsIWeakReference* aShell); + virtual ~nsComboboxWindowAccessible() {} /* ----- nsIAccessible ----- */ NS_IMETHOD GetAccParent(nsIAccessible **_retval); NS_IMETHOD GetAccNextSibling(nsIAccessible **_retval); - NS_IMETHOD GetAccPreviousSibling(nsIAccessible **_retval); - NS_IMETHOD GetAccLastChild(nsIAccessible **_retval); - NS_IMETHOD GetAccFirstChild(nsIAccessible **_retval); NS_IMETHOD GetAccChildCount(PRInt32 *_retval); NS_IMETHOD GetAccRole(PRUint32 *_retval); NS_IMETHOD GetAccState(PRUint32 *_retval); diff --git a/mozilla/accessible/src/html/nsHTMLFormControlAccessible.cpp b/mozilla/accessible/src/html/nsHTMLFormControlAccessible.cpp index 164eea15c29..deb534beab3 100644 --- a/mozilla/accessible/src/html/nsHTMLFormControlAccessible.cpp +++ b/mozilla/accessible/src/html/nsHTMLFormControlAccessible.cpp @@ -37,150 +37,48 @@ * * ***** END LICENSE BLOCK ***** */ -#include "nsHTMLFormControlAccessible.h" -#include "nsWeakReference.h" -#include "nsIDOMHTMLInputElement.h" -#include "nsIDOMHTMLTextAreaElement.h" -#include "nsINameSpaceManager.h" -#include "nsHTMLAtoms.h" -#include "nsIDOMHTMLButtonElement.h" -#include "nsReadableUtils.h" +// NOTE: alphabetically ordered #include "nsAccessible.h" -#include "nsIFrame.h" -#include "nsIDOMHTMLLabelElement.h" +#include "nsFormControlAccessible.h" +#include "nsHTMLAtoms.h" +#include "nsHTMLFormControlAccessible.h" +#include "nsIDOMHTMLButtonElement.h" #include "nsIDOMHTMLFormElement.h" -#include "nsISelectionController.h" +#include "nsIDOMHTMLInputElement.h" +#include "nsIDOMHTMLLabelElement.h" +#include "nsIDOMHTMLTextAreaElement.h" #include "nsIDOMXULCheckboxElement.h" #include "nsIDOMXULButtonElement.h" - -nsHTMLFormControlAccessible::nsHTMLFormControlAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell): -nsLeafAccessible(aNode, aShell) -{ -} - -NS_IMETHODIMP nsHTMLFormControlAccessible::AppendLabelFor(nsIContent *aLookNode, nsAReadableString *aId, nsAWritableString *aLabel) -{ - PRInt32 numChildren = 0; - - nsCOMPtr labelElement(do_QueryInterface(aLookNode)); - if (labelElement) { - nsCOMPtr elt(do_QueryInterface(aLookNode)); - nsresult rv = NS_OK; - - if (elt) { - nsAutoString labelIsFor; - elt->GetAttribute(NS_LITERAL_STRING("for"),labelIsFor); - if (labelIsFor.Equals(*aId)) - rv = AppendFlatStringFromSubtree(aLookNode, aLabel); - } - return rv; - } - - aLookNode->ChildCount(numChildren); - nsIContent *contentWalker; - PRInt32 index; - for (index = 0; index < numChildren; index++) { - aLookNode->ChildAt(index, contentWalker); - if (contentWalker) - AppendLabelFor(contentWalker, aId, aLabel); - } - return NS_OK; -} - -/* wstring getAccName (); */ -NS_IMETHODIMP nsHTMLFormControlAccessible::GetAccName(nsAWritableString& _retval) -{ - nsCOMPtr walkUpContent(do_QueryInterface(mDOMNode)); - nsCOMPtr labelElement; - nsCOMPtr formElement; - nsresult rv = NS_OK; - - nsAutoString label; - // go up tree get name of ancestor label if there is one. Don't go up farther than form element - while (walkUpContent && label.IsEmpty() && !formElement) { - labelElement = do_QueryInterface(walkUpContent); - if (labelElement) - rv = AppendFlatStringFromSubtree(walkUpContent, &label); - formElement = do_QueryInterface(walkUpContent); // reached top ancestor in form - nsCOMPtr nextParent; - walkUpContent->GetParent(*getter_AddRefs(nextParent)); - walkUpContent = nextParent; - } - - - // There can be a label targeted at this control using the for="control_id" attribute - // To save computing time, only look for those inside of a form element - walkUpContent = do_QueryInterface(formElement); - - if (walkUpContent) { - nsCOMPtr elt(do_QueryInterface(mDOMNode)); - nsAutoString forId; - elt->GetAttribute(NS_LITERAL_STRING("id"), forId); - // Actually we'll be walking down the content this time, with a depth first search - if (!forId.IsEmpty()) - AppendLabelFor(walkUpContent,&forId,&label); - } - - label.CompressWhitespace(); - if (label.IsEmpty()) - return nsAccessible::GetAccName(_retval); - - _retval.Assign(label); - - return NS_OK; -} - -/* long getAccState (); */ -NS_IMETHODIMP nsHTMLFormControlAccessible::GetAccState(PRUint32 *_retval) -{ - // can be - // focusable, focused, protected, unavailable - nsCOMPtr htmlFormElement(do_QueryInterface(mDOMNode)); - - nsAccessible::GetAccState(_retval); - - PRBool disabled = PR_FALSE; - if (htmlFormElement) { - htmlFormElement->GetDisabled(&disabled); - nsAutoString typeString; - htmlFormElement->GetType(typeString); - if (typeString.EqualsIgnoreCase("password")) - *_retval |= STATE_PROTECTED; - } - - if (disabled) - *_retval |= STATE_UNAVAILABLE; - else - *_retval |= STATE_FOCUSABLE; - - return NS_OK; -} +#include "nsIDOMXULSelectCntrlItemEl.h" +#include "nsIDOMXULSelectCntrlEl.h" +#include "nsINameSpaceManager.h" +#include "nsIFrame.h" +#include "nsISelectionController.h" +#include "nsReadableUtils.h" +#include "nsWeakReference.h" // --- checkbox ----- nsHTMLCheckboxAccessible::nsHTMLCheckboxAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell): -nsHTMLFormControlAccessible(aNode, aShell) +nsFormControlAccessible(aNode, aShell) { } -/* unsigned long getAccRole (); */ NS_IMETHODIMP nsHTMLCheckboxAccessible::GetAccRole(PRUint32 *_retval) { *_retval = ROLE_CHECKBUTTON; return NS_OK; } -/* PRUint8 getAccNumActions (); */ NS_IMETHODIMP nsHTMLCheckboxAccessible::GetAccNumActions(PRUint8 *_retval) { - *_retval = 1; + *_retval = eSingle_Action; return NS_OK; } -/* wstring getAccActionName (in PRUint8 index); */ NS_IMETHODIMP nsHTMLCheckboxAccessible::GetAccActionName(PRUint8 index, nsAWritableString& _retval) { - if (index == 0) { // 0 is the magic value for default action + if (index == eAction_Click) { // 0 is the magic value for default action // check or uncheck PRUint32 state; GetAccState(&state); @@ -195,7 +93,6 @@ NS_IMETHODIMP nsHTMLCheckboxAccessible::GetAccActionName(PRUint8 index, nsAWrita return NS_ERROR_INVALID_ARG; } -/* void accDoAction (in PRUint8 index); */ NS_IMETHODIMP nsHTMLCheckboxAccessible::AccDoAction(PRUint8 index) { if (index == 0) { // 0 is the magic value for default action @@ -213,7 +110,7 @@ NS_IMETHODIMP nsHTMLCheckboxAccessible::AccDoAction(PRUint8 index) NS_IMETHODIMP nsHTMLCheckboxAccessible::GetAccState(PRUint32 *_retval) { - nsHTMLFormControlAccessible::GetAccState(_retval); + nsFormControlAccessible::GetAccState(_retval); PRBool checked = PR_FALSE; // Radio buttons and check boxes can be checked nsCOMPtr htmlCheckboxElement(do_QueryInterface(mDOMNode)); @@ -229,31 +126,13 @@ NS_IMETHODIMP nsHTMLCheckboxAccessible::GetAccState(PRUint32 *_retval) //------ Radio button ------- nsHTMLRadioButtonAccessible::nsHTMLRadioButtonAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell): -nsHTMLFormControlAccessible(aNode, aShell) +nsRadioButtonAccessible(aNode, aShell) { } -/* PRUint8 getAccNumActions (); */ -NS_IMETHODIMP nsHTMLRadioButtonAccessible::GetAccNumActions(PRUint8 *_retval) -{ - *_retval = 1; - return NS_OK; -} - -/* wstring getAccActionName (in PRUint8 index); */ -NS_IMETHODIMP nsHTMLRadioButtonAccessible::GetAccActionName(PRUint8 index, nsAWritableString& _retval) -{ - if (index == 0) { - _retval = NS_LITERAL_STRING("select"); - return NS_OK; - } - return NS_ERROR_INVALID_ARG; -} - -/* void accDoAction (in PRUint8 index); */ NS_IMETHODIMP nsHTMLRadioButtonAccessible::AccDoAction(PRUint8 index) { - if (index == 0) { + if (index == eAction_Click) { nsCOMPtr element(do_QueryInterface(mDOMNode)); element->Click(); return NS_OK; @@ -261,31 +140,15 @@ NS_IMETHODIMP nsHTMLRadioButtonAccessible::AccDoAction(PRUint8 index) return NS_ERROR_INVALID_ARG; } - -/* unsigned long getAccRole (); */ -NS_IMETHODIMP nsHTMLRadioButtonAccessible::GetAccRole(PRUint32 *_retval) -{ - *_retval = ROLE_RADIOBUTTON; - - return NS_OK; -} - NS_IMETHODIMP nsHTMLRadioButtonAccessible::GetAccState(PRUint32 *_retval) { - nsHTMLFormControlAccessible::GetAccState(_retval); + nsFormControlAccessible::GetAccState(_retval); PRBool checked = PR_FALSE; // Radio buttons and check boxes can be checked nsCOMPtr htmlRadioElement(do_QueryInterface(mDOMNode)); if (htmlRadioElement) htmlRadioElement->GetChecked(&checked); - /* ----- Need to add this code soon - - nsCOMPtr xulRadioElement(do_QueryInteface(mDOMNode)); - if (xulRadioElement) - xulRadioElement->GetChecked(&checked); - */ - if (checked) *_retval |= STATE_CHECKED; @@ -295,28 +158,25 @@ NS_IMETHODIMP nsHTMLRadioButtonAccessible::GetAccState(PRUint32 *_retval) // ----- Button ----- nsHTMLButtonAccessible::nsHTMLButtonAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell): -nsHTMLFormControlAccessible(aNode, aShell) +nsFormControlAccessible(aNode, aShell) { } -/* PRUint8 getAccNumActions (); */ NS_IMETHODIMP nsHTMLButtonAccessible::GetAccNumActions(PRUint8 *_retval) { - *_retval = 1; + *_retval = eSingle_Action; return NS_OK;; } -/* wstring getAccActionName (in PRUint8 index); */ NS_IMETHODIMP nsHTMLButtonAccessible::GetAccActionName(PRUint8 index, nsAWritableString& _retval) { - if (index == 0) { + if (index == eAction_Click) { _retval = NS_LITERAL_STRING("press"); return NS_OK; } return NS_ERROR_INVALID_ARG; } -/* void accDoAction (in PRUint8 index); */ NS_IMETHODIMP nsHTMLButtonAccessible::AccDoAction(PRUint8 index) { if (index == 0) { @@ -327,14 +187,12 @@ NS_IMETHODIMP nsHTMLButtonAccessible::AccDoAction(PRUint8 index) return NS_ERROR_INVALID_ARG; } -/* unsigned long getAccRole (); */ NS_IMETHODIMP nsHTMLButtonAccessible::GetAccRole(PRUint32 *_retval) { *_retval = ROLE_PUSHBUTTON; return NS_OK; } -/* wstring getAccName (); */ NS_IMETHODIMP nsHTMLButtonAccessible::GetAccName(nsAWritableString& _retval) { nsCOMPtr button(do_QueryInterface(mDOMNode)); @@ -358,24 +216,21 @@ nsBlockAccessible(aNode, aShell) { } -/* PRUint8 getAccNumActions (); */ NS_IMETHODIMP nsHTML4ButtonAccessible::GetAccNumActions(PRUint8 *_retval) { - *_retval = 1; + *_retval = eSingle_Action; return NS_OK;; } -/* wstring getAccActionName (in PRUint8 index); */ NS_IMETHODIMP nsHTML4ButtonAccessible::GetAccActionName(PRUint8 index, nsAWritableString& _retval) { - if (index == 0) { + if (index == eAction_Click) { _retval = NS_LITERAL_STRING("press"); return NS_OK; } return NS_ERROR_INVALID_ARG; } -/* void accDoAction (in PRUint8 index); */ NS_IMETHODIMP nsHTML4ButtonAccessible::AccDoAction(PRUint8 index) { if (index == 0) { @@ -390,14 +245,12 @@ NS_IMETHODIMP nsHTML4ButtonAccessible::AccDoAction(PRUint8 index) return NS_ERROR_INVALID_ARG; } -/* unsigned long getAccRole (); */ NS_IMETHODIMP nsHTML4ButtonAccessible::GetAccRole(PRUint32 *_retval) { *_retval = ROLE_PUSHBUTTON; return NS_OK; } -/* long getAccState (); */ NS_IMETHODIMP nsHTML4ButtonAccessible::GetAccState(PRUint32 *_retval) { nsAccessible::GetAccState(_retval); @@ -405,8 +258,6 @@ NS_IMETHODIMP nsHTML4ButtonAccessible::GetAccState(PRUint32 *_retval) return NS_OK; } - -/* wstring getAccName (); */ NS_IMETHODIMP nsHTML4ButtonAccessible::GetAccName(nsAWritableString& _retval) { nsresult rv = NS_ERROR_FAILURE; @@ -429,18 +280,16 @@ NS_IMETHODIMP nsHTML4ButtonAccessible::GetAccName(nsAWritableString& _retval) // --- textfield ----- nsHTMLTextFieldAccessible::nsHTMLTextFieldAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell): -nsHTMLFormControlAccessible(aNode, aShell) +nsFormControlAccessible(aNode, aShell) { } -/* unsigned long getAccRole (); */ NS_IMETHODIMP nsHTMLTextFieldAccessible::GetAccRole(PRUint32 *_retval) { *_retval = ROLE_TEXT; return NS_OK; } -/* wstring getAccValue (); */ NS_IMETHODIMP nsHTMLTextFieldAccessible::GetAccValue(nsAWritableString& _retval) { PRUint32 state; @@ -463,7 +312,6 @@ NS_IMETHODIMP nsHTMLTextFieldAccessible::GetAccValue(nsAWritableString& _retval) return NS_ERROR_FAILURE; } -/* long getAccState (); */ NS_IMETHODIMP nsHTMLTextFieldAccessible::GetAccState(PRUint32 *_retval) { // can be @@ -511,7 +359,7 @@ NS_IMETHODIMP nsHTMLTextFieldAccessible::GetAccState(PRUint32 *_retval) if (inputElement) { /////// ====== Must be a password field, so it uses nsIDOMHTMLFormControl ==== /////// PRUint32 moreStates = 0; - nsresult rv = nsHTMLFormControlAccessible::GetAccState(&moreStates); + nsresult rv = nsFormControlAccessible::GetAccState(&moreStates); *_retval |= moreStates; return rv; } diff --git a/mozilla/accessible/src/html/nsHTMLFormControlAccessible.h b/mozilla/accessible/src/html/nsHTMLFormControlAccessible.h index 13ab8ceb00a..59fa72afcf2 100644 --- a/mozilla/accessible/src/html/nsHTMLFormControlAccessible.h +++ b/mozilla/accessible/src/html/nsHTMLFormControlAccessible.h @@ -40,29 +40,12 @@ #ifndef _nsHTMLFormControlAccessible_H_ #define _nsHTMLFormControlAccessible_H_ -#include "nsAccessible.h" #include "nsBaseWidgetAccessible.h" +#include "nsFormControlAccessible.h" class nsICheckboxControlFrame; -/* Accessible for supporting for controls - * supports: - * - walking up to get name from label - * - support basic state - */ -class nsHTMLFormControlAccessible : public nsLeafAccessible -{ - -public: - nsHTMLFormControlAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell); - NS_IMETHOD GetAccName(nsAWritableString& _retval); - NS_IMETHOD GetAccState(PRUint32 *_retval); - -protected: - NS_IMETHODIMP AppendLabelFor(nsIContent *aLookNode, nsAReadableString *aId, nsAWritableString *aLabel); -}; - -class nsHTMLCheckboxAccessible : public nsHTMLFormControlAccessible +class nsHTMLCheckboxAccessible : public nsFormControlAccessible { public: @@ -74,19 +57,16 @@ public: NS_IMETHOD GetAccState(PRUint32 *_retval); }; -class nsHTMLRadioButtonAccessible : public nsHTMLFormControlAccessible +class nsHTMLRadioButtonAccessible : public nsRadioButtonAccessible { public: nsHTMLRadioButtonAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell); - NS_IMETHOD GetAccRole(PRUint32 *_retval); - NS_IMETHOD GetAccNumActions(PRUint8 *_retval); - NS_IMETHOD GetAccActionName(PRUint8 index, nsAWritableString& _retval); NS_IMETHOD AccDoAction(PRUint8 index); NS_IMETHOD GetAccState(PRUint32 *_retval); }; -class nsHTMLButtonAccessible : public nsHTMLFormControlAccessible +class nsHTMLButtonAccessible : public nsFormControlAccessible { public: @@ -111,8 +91,7 @@ public: NS_IMETHOD AccDoAction(PRUint8 index); }; - -class nsHTMLTextFieldAccessible : public nsHTMLFormControlAccessible +class nsHTMLTextFieldAccessible : public nsFormControlAccessible { public: nsHTMLTextFieldAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell); diff --git a/mozilla/accessible/src/html/nsHTMLSelectAccessible.cpp b/mozilla/accessible/src/html/nsHTMLSelectAccessible.cpp index 3821122d361..0be4b1a43c8 100644 --- a/mozilla/accessible/src/html/nsHTMLSelectAccessible.cpp +++ b/mozilla/accessible/src/html/nsHTMLSelectAccessible.cpp @@ -37,680 +37,77 @@ * * ***** END LICENSE BLOCK ***** */ -#include "nsHTMLSelectAccessible.h" #include "nsCOMPtr.h" -#include "nsIDocument.h" -#include "nsIPresShell.h" -#include "nsIPresContext.h" -#include "nsIContent.h" -#include "nsIFrame.h" -#include "nsRootAccessible.h" -#include "nsINameSpaceManager.h" -#include "nsIDOMHTMLInputElement.h" -#include "nsLayoutAtoms.h" -#include "nsIDOMXULListener.h" -#include "nsIDOMEventReceiver.h" -#include "nsReadableUtils.h" -#include "nsIDOMHTMLCollection.h" -#include "nsISelectElement.h" -#include "nsIDOMHTMLSelectElement.h" +#include "nsHTMLSelectAccessible.h" #include "nsIAccessibilityService.h" -#include "nsIServiceManager.h" +#include "nsIFrame.h" +#include "nsIComboboxControlFrame.h" +#include "nsIDOMEventReceiver.h" +#include "nsIDOMHTMLCollection.h" +#include "nsIDOMHTMLInputElement.h" #include "nsIDOMHTMLOptionElement.h" - -/* - * A class the represents the text field in the Select to the left - * of the drop down button - */ -class nsHTMLSelectTextFieldAccessible : public nsLeafAccessible -{ -public: - - nsHTMLSelectTextFieldAccessible(nsIAccessible* aParent, nsIDOMNode* aDOMNode, nsIWeakReference* aShell); - - NS_IMETHOD GetAccNextSibling(nsIAccessible **_retval); - NS_IMETHOD GetAccPreviousSibling(nsIAccessible **_retval); - NS_IMETHOD GetAccParent(nsIAccessible **_retval); - NS_IMETHOD GetAccRole(PRUint32 *_retval); - NS_IMETHOD GetAccValue(nsAWritableString& _retval); - - virtual void GetBounds(nsRect& aBounds, nsIFrame** aRelativeFrame); - - nsCOMPtr mParent; -}; - -/* - * A base class that can listen to menu events. Its used so the - * button and the window accessibles can change there name and role - * depending on whether the drop down list is dropped down on not - */ -class nsMenuListenerAccessible : public nsAccessible, public nsIDOMXULListener -{ -public: - - NS_DECL_ISUPPORTS_INHERITED - - nsMenuListenerAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell); - virtual ~nsMenuListenerAccessible(); - - // popup listener - 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(); - - PRBool mRegistered; - PRBool mOpen; -}; - -NS_IMPL_ISUPPORTS_INHERITED1(nsMenuListenerAccessible, nsAccessible, nsIDOMXULListener) +#include "nsIDOMHTMLSelectElement.h" +#include "nsIListControlFrame.h" +#include "nsIServiceManager.h" +#include "nsLayoutAtoms.h" /** - * A class that represents the button inside the Select to the right of the text field - */ -class nsHTMLSelectButtonAccessible : public nsMenuListenerAccessible -{ -public: - - nsHTMLSelectButtonAccessible(nsIAccessible* aParent, nsIDOMNode* aDOMNode, nsIWeakReference* aShell); + * Selects, Listboxes and Comboboxes, are made up of a number of different + * widgets, some of which are shared between the two. This file contains + * all of the widgets for both of the Selects, for HTML only. Some of them + * extend classes from nsSelectAccessible.cpp, which contains base classes + * that are also extended by the XUL Select Accessibility support. + * + * Listbox: + * - nsHTMLListboxAccessible + * - nsHTMLSelctListAccessible + * - nsHTMLSelectOptionAccessible + * + * Comboboxes: + * - nsHTMLComboboxAccessilbe + * - nsHTMLComboboxTextFieldAccessible + * - nsHTMLComboboxButtonAccessible + * - nsHTMLComboboxWindowAccessilbe + * - nsHTMLSelctListAccessible + * - nsHTMLSelectOptionAccessible + */ - NS_IMETHOD GetAccNextSibling(nsIAccessible **_retval); - NS_IMETHOD GetAccPreviousSibling(nsIAccessible **_retval); - NS_IMETHOD GetAccParent(nsIAccessible **_retval); - NS_IMETHOD GetAccName(nsAWritableString& _retval); - NS_IMETHOD GetAccRole(PRUint32 *_retval); - NS_IMETHOD GetAccLastChild(nsIAccessible **_retval); - NS_IMETHOD GetAccFirstChild(nsIAccessible **_retval); - NS_IMETHOD GetAccChildCount(PRInt32 *_retval); - NS_IMETHOD GetAccNumActions(PRUint8 *_retval); - NS_IMETHOD GetAccActionName(PRUint8 index, nsAWritableString& _retval); - NS_IMETHOD AccDoAction(PRUint8 index); +/** ------------------------------------------------------ */ +/** First, the common widgets */ +/** ------------------------------------------------------ */ +/** ----- nsHTMLSelectListAccessible ----- */ - virtual void GetBounds(nsRect& aBounds, nsIFrame** aRelativeFrame); - - - - nsCOMPtr mParent; -}; - -/* - * A class that represents the window that lives to the right - * of the drop down button inside the Select. This is the window - * that is made visible when the button is pressed. - */ -class nsHTMLSelectWindowAccessible : public nsMenuListenerAccessible -{ -public: - - nsHTMLSelectWindowAccessible(nsIAccessible* aParent, nsIDOMNode* aDOMNode, nsIWeakReference* aShell); - - NS_IMETHOD GetAccParent(nsIAccessible **_retval); - NS_IMETHOD GetAccNextSibling(nsIAccessible **_retval); - NS_IMETHOD GetAccPreviousSibling(nsIAccessible **_retval); - NS_IMETHOD GetAccLastChild(nsIAccessible **_retval); - NS_IMETHOD GetAccFirstChild(nsIAccessible **_retval); - NS_IMETHOD GetAccChildCount(PRInt32 *_retval); - NS_IMETHOD GetAccRole(PRUint32 *_retval); - NS_IMETHOD GetAccState(PRUint32 *_retval); - - virtual void GetBounds(nsRect& aBounds, nsIFrame** aRelativeFrame); - - nsCOMPtr mParent; -}; - -/* - * The list that contains all the options in the select. It is inside the window. - */ -class nsHTMLSelectListAccessible : public nsAccessible -{ -public: - - nsHTMLSelectListAccessible(nsIAccessible* aParent, nsIDOMNode* aDOMNode, nsIWeakReference* aShell); - virtual ~nsHTMLSelectListAccessible() {} - - NS_IMETHOD GetAccParent(nsIAccessible **_retval); - NS_IMETHOD GetAccRole(PRUint32 *_retval); - NS_IMETHOD GetAccNextSibling(nsIAccessible **_retval); - NS_IMETHOD GetAccPreviousSibling(nsIAccessible **_retval); - NS_IMETHOD AccGetBounds(PRInt32 *x, PRInt32 *y, PRInt32 *width, PRInt32 *height); - NS_IMETHOD GetAccLastChild(nsIAccessible **_retval); - NS_IMETHOD GetAccFirstChild(nsIAccessible **_retval); - - nsCOMPtr mParent; -}; - -//--------- nsHTMLSelectAccessible ----- - -nsHTMLSelectAccessible::nsHTMLSelectAccessible(nsIDOMNode* aDOMNode, - nsIWeakReference* aShell) - :nsAccessible(aDOMNode, aShell) +/** Default Constructor */ +nsHTMLSelectListAccessible::nsHTMLSelectListAccessible(nsIAccessible* aParent, + nsIDOMNode* aDOMNode, + nsIWeakReference* aShell) +:nsSelectListAccessible(aParent, aDOMNode, aShell) { } -NS_IMPL_ISUPPORTS_INHERITED1(nsHTMLSelectAccessible, nsAccessible, nsIAccessibleSelectable) - -// ------------- Helper method for determination of proper Frame ------ -//static -PRBool nsHTMLSelectAccessible::IsCorrectFrame( nsIFrame* aFrame, nsIAtom* aAtom ) { - if (!aFrame || !aAtom) - return PR_FALSE; - nsCOMPtr frameType; - aFrame->GetFrameType(getter_AddRefs(frameType)); - if (frameType.get() != aAtom) - return PR_FALSE; - return PR_TRUE; -} - -NS_IMETHODIMP nsHTMLSelectAccessible::GetAccValue(nsAWritableString& _retval) +/** + * As a nsHTMLSelectListAccessible we can have the following states: + * STATE_MULTISELECTABLE + * STATE_EXTSELECTABLE + */ +NS_IMETHODIMP nsHTMLSelectListAccessible::GetAccState(PRUint32 *_retval) { - nsCOMPtr text; - GetAccFirstChild(getter_AddRefs(text)); - if (text) - return text->GetAccValue(_retval); - - return NS_ERROR_FAILURE; -} - - -NS_IMETHODIMP nsHTMLSelectAccessible::GetAccRole(PRUint32 *_retval) -{ - *_retval = ROLE_COMBOBOX; - return NS_OK; -} - -NS_IMETHODIMP nsHTMLSelectAccessible::GetAccLastChild(nsIAccessible **_retval) -{ - // create a window accessible - *_retval = new nsHTMLSelectWindowAccessible(this, mDOMNode, mPresShell); - if ( ! *_retval ) - return NS_ERROR_FAILURE; - NS_ADDREF(*_retval); - return NS_OK; -} - -NS_IMETHODIMP nsHTMLSelectAccessible::GetAccFirstChild(nsIAccessible **_retval) -{ - // create a text field - - *_retval = new nsHTMLSelectTextFieldAccessible(this, mDOMNode, mPresShell); - if ( ! *_retval ) - return NS_ERROR_FAILURE; - NS_ADDREF(*_retval); - return NS_OK; -} - -NS_IMETHODIMP nsHTMLSelectAccessible::GetAccChildCount(PRInt32 *_retval) -{ - // always have 3 children - *_retval = 3; - return NS_OK; -} - -NS_IMETHODIMP nsHTMLSelectAccessible::GetSelectedChildren(nsISupportsArray **_retval) -{ - *_retval = nsnull; - return NS_OK; -} - -//-------- SelectTextFieldAccessible ------ - -nsHTMLSelectTextFieldAccessible::nsHTMLSelectTextFieldAccessible(nsIAccessible* aParent, nsIDOMNode* aDOMNode, nsIWeakReference* aShell): -nsLeafAccessible(aDOMNode, aShell) -{ - mParent = aParent; -} - -NS_IMETHODIMP nsHTMLSelectTextFieldAccessible::GetAccValue(nsAWritableString& _retval) -{ - nsIFrame* frame = nsAccessible::GetBoundsFrame(); - nsCOMPtr context; - GetPresContext(context); - if ( !frame ) - return NS_ERROR_FAILURE; - - frame->FirstChild(context, nsnull, &frame); - if ( ! nsHTMLSelectAccessible::IsCorrectFrame( frame, nsLayoutAtoms::blockFrame) ) - return NS_ERROR_FAILURE; - - frame->FirstChild(context, nsnull, &frame); - if ( ! nsHTMLSelectAccessible::IsCorrectFrame( frame, nsLayoutAtoms::textFrame) ) - return NS_ERROR_FAILURE; - - nsCOMPtr content; - frame->GetContent(getter_AddRefs(content)); - - if (!content) - return NS_ERROR_FAILURE; - - AppendFlatStringFromSubtree(content, &_retval); - - return NS_OK; -} - -void nsHTMLSelectTextFieldAccessible::GetBounds(nsRect& aBounds, nsIFrame** aRelativeFrame) -{ - // get our first child's frame - nsIFrame* frame = nsAccessible::GetBoundsFrame(); - nsCOMPtr context; - GetPresContext(context); - if ( !frame ) - return; - - frame->FirstChild(context, nsnull, &frame); - if ( ! nsHTMLSelectAccessible::IsCorrectFrame( frame, nsLayoutAtoms::blockFrame) ) - return; - - frame->GetParent(aRelativeFrame); - if ( ! nsHTMLSelectAccessible::IsCorrectFrame( *aRelativeFrame, nsLayoutAtoms::areaFrame) ) - return; - - frame->GetRect(aBounds); -} - -NS_IMETHODIMP nsHTMLSelectTextFieldAccessible::GetAccParent(nsIAccessible **_retval) -{ - *_retval = mParent; - NS_IF_ADDREF(*_retval); - return NS_OK; -} - -NS_IMETHODIMP nsHTMLSelectTextFieldAccessible::GetAccNextSibling(nsIAccessible **_retval) -{ - nsCOMPtr parent; - GetAccParent(getter_AddRefs(parent)); - - *_retval = new nsHTMLSelectButtonAccessible(parent, mDOMNode, mPresShell); - if ( ! *_retval ) - return NS_ERROR_FAILURE; - NS_ADDREF(*_retval); - return NS_OK; -} - -NS_IMETHODIMP nsHTMLSelectTextFieldAccessible::GetAccPreviousSibling(nsIAccessible **_retval) -{ - *_retval = nsnull; - return NS_OK; -} - -NS_IMETHODIMP nsHTMLSelectTextFieldAccessible::GetAccRole(PRUint32 *_retval) -{ - *_retval = ROLE_STATICTEXT; - return NS_OK; -} - -// --------- nsMenuListenerAccessible ----------- - -nsMenuListenerAccessible::nsMenuListenerAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell): -nsAccessible(aDOMNode, aShell) -{ - mRegistered = PR_FALSE; - mOpen = PR_FALSE; -} - -nsMenuListenerAccessible::~nsMenuListenerAccessible() -{ - if (mRegistered) { - nsCOMPtr eventReceiver(do_QueryInterface(mDOMNode)); - if (eventReceiver) - eventReceiver->RemoveEventListener(NS_LITERAL_STRING("popupshowing"), this, PR_TRUE); - } -} - -NS_IMETHODIMP nsMenuListenerAccessible::PopupShowing(nsIDOMEvent* aEvent) -{ - mOpen = PR_TRUE; - - /* TBD send state change event */ - - return NS_OK; -} - -NS_IMETHODIMP nsMenuListenerAccessible::PopupHiding(nsIDOMEvent* aEvent) -{ - mOpen = PR_FALSE; - - /* TBD send state change event */ - - return NS_OK; -} - -NS_IMETHODIMP nsMenuListenerAccessible::Close(nsIDOMEvent* aEvent) -{ - mOpen = PR_FALSE; - - /* TBD send state change event */ - - return NS_OK; -} - -void -nsMenuListenerAccessible::SetupMenuListener() -{ - // not not already one register ourselves as a popup listener - if (!mRegistered) { - - nsCOMPtr eventReceiver(do_QueryInterface(mDOMNode)); - if (!eventReceiver) { - return; - } - - nsresult rv = eventReceiver->AddEventListener(NS_LITERAL_STRING("popupshowing"), this, PR_TRUE); - - if (NS_FAILED(rv)) { - return; - } - - mRegistered = PR_TRUE; + nsCOMPtr select (do_QueryInterface(mDOMNode)); + if ( select ) { + PRBool multiple; + select->GetMultiple(&multiple); + if ( multiple ) + *_retval |= STATE_MULTISELECTABLE | STATE_EXTSELECTABLE; } -} - - -//-------- SelectButtonAccessible ------ - -nsHTMLSelectButtonAccessible::nsHTMLSelectButtonAccessible(nsIAccessible* aParent, nsIDOMNode* aDOMNode, nsIWeakReference* aShell): -nsMenuListenerAccessible(aDOMNode, aShell) -{ - mParent = aParent; -} - -/* void accDoAction (in PRUint8 index); */ -NS_IMETHODIMP nsHTMLSelectButtonAccessible::AccDoAction(PRUint8 index) -{ - nsIFrame* frame = nsAccessible::GetBoundsFrame(); - nsCOMPtr context; - GetPresContext(context); - - frame->FirstChild(context, nsnull, &frame); - if ( ! nsHTMLSelectAccessible::IsCorrectFrame( frame, nsLayoutAtoms::blockFrame) ) - return NS_ERROR_FAILURE; - - frame->GetNextSibling(&frame); - if ( ! nsHTMLSelectAccessible::IsCorrectFrame( frame, nsLayoutAtoms::gfxButtonControlFrame) ) - return NS_ERROR_FAILURE; - - nsCOMPtr content; - frame->GetContent(getter_AddRefs(content)); - - if (index == 0) { - nsCOMPtr element(do_QueryInterface(content)); - if (element) - { - element->Click(); - return NS_OK; - } - return NS_ERROR_FAILURE; - } - return NS_ERROR_NOT_IMPLEMENTED; -} - -/* PRUint8 getAccNumActions (); */ -NS_IMETHODIMP nsHTMLSelectButtonAccessible::GetAccNumActions(PRUint8 *_retval) -{ - *_retval = 1; - return NS_OK; -} - -void nsHTMLSelectButtonAccessible::GetBounds(nsRect& aBounds, nsIFrame** aRelativeFrame) -{ - // get our second child's frame - nsIFrame* frame = nsAccessible::GetBoundsFrame(); - nsCOMPtr context; - GetPresContext(context); - - frame->FirstChild(context, nsnull, &frame); - if ( ! nsHTMLSelectAccessible::IsCorrectFrame( frame, nsLayoutAtoms::blockFrame) ) - return; - - frame->GetNextSibling(&frame); - if ( ! nsHTMLSelectAccessible::IsCorrectFrame( frame, nsLayoutAtoms::gfxButtonControlFrame) ) - return; - - frame->GetParent(aRelativeFrame); - if ( ! nsHTMLSelectAccessible::IsCorrectFrame( *aRelativeFrame, nsLayoutAtoms::areaFrame) ) - return; - - frame->GetRect(aBounds); -} - -NS_IMETHODIMP nsHTMLSelectButtonAccessible::GetAccRole(PRUint32 *_retval) -{ - *_retval = ROLE_PUSHBUTTON; - return NS_OK; -} - -NS_IMETHODIMP nsHTMLSelectButtonAccessible::GetAccParent(nsIAccessible **_retval) -{ - *_retval = mParent; - NS_IF_ADDREF(*_retval); - return NS_OK; -} - - -NS_IMETHODIMP nsHTMLSelectButtonAccessible::GetAccName(nsAWritableString& _retval) -{ - return GetAccActionName(0, _retval); -} - -NS_IMETHODIMP nsHTMLSelectButtonAccessible::GetAccActionName(PRUint8 index, nsAWritableString& _retval) -{ - SetupMenuListener(); - - // get the current state open or closed - // set _retval to it. - // notice its supposed to be reversed. Close if opened - // and Open if closed. - - if (mOpen) - _retval = NS_LITERAL_STRING("Close"); - else - _retval = NS_LITERAL_STRING("Open"); - - return NS_OK; -} - - -NS_IMETHODIMP nsHTMLSelectButtonAccessible::GetAccNextSibling(nsIAccessible **_retval) -{ - nsCOMPtr parent; - GetAccParent(getter_AddRefs(parent)); - - *_retval = new nsHTMLSelectWindowAccessible(parent, mDOMNode, mPresShell); - if ( ! *_retval ) - return NS_ERROR_FAILURE; - NS_ADDREF(*_retval); - return NS_OK; -} - -NS_IMETHODIMP nsHTMLSelectButtonAccessible::GetAccPreviousSibling(nsIAccessible **_retval) -{ - nsCOMPtr parent; - GetAccParent(getter_AddRefs(parent)); - - *_retval = new nsHTMLSelectTextFieldAccessible(parent, mDOMNode, mPresShell); - if ( ! *_retval ) - return NS_ERROR_FAILURE; - NS_ADDREF(*_retval); - return NS_OK; -} - -NS_IMETHODIMP nsHTMLSelectButtonAccessible::GetAccLastChild(nsIAccessible **_retval) -{ - *_retval = nsnull; - return NS_OK; -} - -NS_IMETHODIMP nsHTMLSelectButtonAccessible::GetAccFirstChild(nsIAccessible **_retval) -{ - *_retval = nsnull; - return NS_OK; -} - -NS_IMETHODIMP nsHTMLSelectButtonAccessible::GetAccChildCount(PRInt32 *_retval) -{ - *_retval = 0; - return NS_OK; -} - -//--------------------- - - -nsHTMLSelectWindowAccessible::nsHTMLSelectWindowAccessible(nsIAccessible* aParent, nsIDOMNode* aDOMNode, nsIWeakReference* aShell) -:nsMenuListenerAccessible(aDOMNode, aShell) -{ - mParent = aParent; -} - - -NS_IMETHODIMP nsHTMLSelectWindowAccessible::GetAccState(PRUint32 *_retval) -{ - nsAccessible::GetAccState(_retval); - - SetupMenuListener(); - - // if open we are visible if closed we are invisible - // set _retval to it. - if (mOpen) - *_retval |= STATE_DEFAULT; - else - *_retval |= STATE_INVISIBLE; - - return NS_OK; -} - -NS_IMETHODIMP nsHTMLSelectWindowAccessible::GetAccRole(PRUint32 *_retval) -{ - *_retval = ROLE_WINDOW; - return NS_OK; -} - -NS_IMETHODIMP nsHTMLSelectWindowAccessible::GetAccParent(nsIAccessible **_retval) -{ - *_retval = mParent; - NS_IF_ADDREF(*_retval); - return NS_OK; -} - -NS_IMETHODIMP nsHTMLSelectWindowAccessible::GetAccPreviousSibling(nsIAccessible **_retval) -{ - nsCOMPtr parent; - GetAccParent(getter_AddRefs(parent)); - - *_retval = new nsHTMLSelectButtonAccessible(parent, mDOMNode, mPresShell); - if ( ! *_retval ) - return NS_ERROR_FAILURE; - NS_ADDREF(*_retval); - return NS_OK; -} - -NS_IMETHODIMP nsHTMLSelectWindowAccessible::GetAccNextSibling(nsIAccessible **_retval) -{ - *_retval = nsnull; - return NS_OK; -} - -NS_IMETHODIMP nsHTMLSelectWindowAccessible::GetAccLastChild(nsIAccessible **_retval) -{ - *_retval = new nsHTMLSelectListAccessible(this, mDOMNode, mPresShell); - if ( ! *_retval ) - return NS_ERROR_FAILURE; - NS_ADDREF(*_retval); - return NS_OK; -} - -NS_IMETHODIMP nsHTMLSelectWindowAccessible::GetAccFirstChild(nsIAccessible **_retval) -{ - *_retval = new nsHTMLSelectListAccessible(this, mDOMNode, mPresShell); - if ( ! *_retval ) - return NS_ERROR_FAILURE; - NS_ADDREF(*_retval); - return NS_OK; -} - -NS_IMETHODIMP nsHTMLSelectWindowAccessible::GetAccChildCount(PRInt32 *_retval) -{ - *_retval = 1; - return NS_OK; -} - -void nsHTMLSelectWindowAccessible::GetBounds(nsRect& aBounds, nsIFrame** aRelativeFrame) -{ - // get our first option - nsCOMPtr child; - mDOMNode->GetFirstChild(getter_AddRefs(child)); - - // now get its frame - nsCOMPtr shell(do_QueryReferent(mPresShell)); - if (!shell) { - *aRelativeFrame = nsnull; - return; - } - - nsIFrame* frame = nsnull; - nsCOMPtr content(do_QueryInterface(child)); - shell->GetPrimaryFrameFor(content, &frame); - if ( ! nsHTMLSelectAccessible::IsCorrectFrame( frame, nsLayoutAtoms::blockFrame) ) - return; - - frame->GetParent(&frame); - if ( ! nsHTMLSelectAccessible::IsCorrectFrame( frame, nsLayoutAtoms::areaFrame) ) - return; - - frame->GetParent(aRelativeFrame); - if ( ! nsHTMLSelectAccessible::IsCorrectFrame( *aRelativeFrame, nsLayoutAtoms::listControlFrame) ) - return; - - frame->GetRect(aBounds); -} - -//---------- - - -nsHTMLSelectListAccessible::nsHTMLSelectListAccessible(nsIAccessible* aParent, nsIDOMNode* aDOMNode, nsIWeakReference* aShell) -:nsAccessible(aDOMNode, aShell) -{ - mParent = aParent; -} - -NS_IMETHODIMP nsHTMLSelectListAccessible::AccGetBounds(PRInt32 *x, PRInt32 *y, PRInt32 *width, PRInt32 *height) -{ - return mParent->AccGetBounds(x,y,width,height); -} - -NS_IMETHODIMP nsHTMLSelectListAccessible::GetAccParent(nsIAccessible **_retval) -{ - *_retval = mParent; - NS_ADDREF(*_retval); - return NS_OK; -} - -NS_IMETHODIMP nsHTMLSelectListAccessible::GetAccRole(PRUint32 *_retval) -{ - *_retval = ROLE_LIST; - return NS_OK; -} - -NS_IMETHODIMP nsHTMLSelectListAccessible::GetAccPreviousSibling(nsIAccessible **_retval) -{ - *_retval = nsnull; - return NS_OK; -} - -NS_IMETHODIMP nsHTMLSelectListAccessible::GetAccNextSibling(nsIAccessible **_retval) -{ - *_retval = nsnull; return NS_OK; } +/** + * Gets the last child of the DOM node and creates and returns + * a nsHTMLSelectOptionAccessible. + */ NS_IMETHODIMP nsHTMLSelectListAccessible::GetAccLastChild(nsIAccessible **_retval) { nsCOMPtr last; @@ -723,6 +120,10 @@ NS_IMETHODIMP nsHTMLSelectListAccessible::GetAccLastChild(nsIAccessible **_retva return NS_OK; } +/** + * Gets the First child of the DOM node and creates and returns + * a nsHTMLSelectOptionAccessible. + */ NS_IMETHODIMP nsHTMLSelectListAccessible::GetAccFirstChild(nsIAccessible **_retval) { nsCOMPtr first; @@ -735,27 +136,18 @@ NS_IMETHODIMP nsHTMLSelectListAccessible::GetAccFirstChild(nsIAccessible **_retv return NS_OK; } -//-------- +/** ----- nsHTMLSelectOptionAccessible ----- */ +/** Default Constructor */ nsHTMLSelectOptionAccessible::nsHTMLSelectOptionAccessible(nsIAccessible* aParent, nsIDOMNode* aDOMNode, nsIWeakReference* aShell): -nsLeafAccessible(aDOMNode, aShell) +nsSelectOptionAccessible(aParent, aDOMNode, aShell) { - mParent = aParent; -} - -NS_IMETHODIMP nsHTMLSelectOptionAccessible::GetAccRole(PRUint32 *_retval) -{ - *_retval = ROLE_LISTITEM; - return NS_OK; -} - -NS_IMETHODIMP nsHTMLSelectOptionAccessible::GetAccParent(nsIAccessible **_retval) -{ - *_retval = mParent; - NS_IF_ADDREF(*_retval); - return NS_OK; } +/** + * Gets the next sibling of the DOM node and creates and returns + * a nsHTMLSelectOptionAccessible. + */ NS_IMETHODIMP nsHTMLSelectOptionAccessible::GetAccNextSibling(nsIAccessible **_retval) { *_retval = nsnull; @@ -773,6 +165,10 @@ NS_IMETHODIMP nsHTMLSelectOptionAccessible::GetAccNextSibling(nsIAccessible **_r return NS_OK; } +/** + * Gets the previous sibling of the DOM node and creates and returns + * a nsHTMLSelectOptionAccessible. + */ NS_IMETHODIMP nsHTMLSelectOptionAccessible::GetAccPreviousSibling(nsIAccessible **_retval) { *_retval = nsnull; @@ -790,20 +186,404 @@ NS_IMETHODIMP nsHTMLSelectOptionAccessible::GetAccPreviousSibling(nsIAccessible return NS_OK; } -NS_IMETHODIMP nsHTMLSelectOptionAccessible::GetAccName(nsAWritableString& _retval) +/** + * As a nsHTMLSelectOptionAccessible we can have the following states: + * STATE_SELECTABLE + * STATE_SELECTED + * STATE_FOCUSED + * STATE_FOCUSABLE + * STATE_INVISIBLE -- not implemented yet + */ +NS_IMETHODIMP nsHTMLSelectOptionAccessible::GetAccState(PRUint32 *_retval) { - nsCOMPtr content (do_QueryInterface(mDOMNode)); - if (!content) { - return NS_ERROR_FAILURE; + *_retval = 0; + nsCOMPtr focusedOptionNode, parentNode; + mParent->AccGetDOMNode(getter_AddRefs(parentNode)); + // find out if we are the focused node + GetFocusedOptionNode(mPresShell, parentNode, focusedOptionNode); + if (focusedOptionNode == mDOMNode) + *_retval |= STATE_FOCUSED; + + // Are we selected? + nsCOMPtr option (do_QueryInterface(mDOMNode)); + if ( option ) { + PRBool isSelected = PR_FALSE; + option->GetSelected(&isSelected); + if ( isSelected ) + *_retval |= STATE_SELECTED; } - nsAutoString option; - nsresult rv = AppendFlatStringFromSubtree(content, &option); + *_retval |= STATE_SELECTABLE | STATE_FOCUSABLE; + + return NS_OK; +} + +/** + * Helper method for getting the focused DOM Node from our parent(list) node. We + * need to use the frame to get the focused option because for some reason we + * weren't getting the proper notification when the focus changed using the DOM + */ +nsresult nsHTMLSelectOptionAccessible::GetFocusedOptionNode(nsIWeakReference *aPresShell, + nsIDOMNode *aListNode, + nsCOMPtr& aFocusedOptionNode) +{ + NS_ASSERTION(aListNode, "Called GetFocusedOptionNode without a valid list node"); + nsCOMPtr shell(do_QueryReferent(aPresShell)); + if (!shell) + return NS_ERROR_FAILURE; + + nsIFrame *frame = nsnull; + nsCOMPtr content(do_QueryInterface(aListNode)); + shell->GetPrimaryFrameFor(content, &frame); + + nsresult rv; + nsCOMPtr listFrame(do_QueryInterface(frame, &rv)); + if (NS_FAILED(rv)) + return rv; // How can list content not have a list frame? + NS_ASSERTION(listFrame, "We don't have a list frame, but rv returned a success code."); + + // Get what's focused by asking frame for "selected item". + PRInt32 focusedOptionIndex = 0; + rv = listFrame->GetSelectedIndex(&focusedOptionIndex); + + nsCOMPtr options; + + // Get options if (NS_SUCCEEDED(rv)) { - // Temp var needed until CompressWhitespace built for nsAWritableString - option.CompressWhitespace(); - _retval.Assign(option); + nsCOMPtr selectElement(do_QueryInterface(aListNode)); + NS_ASSERTION(selectElement, "No select element where it should be"); + rv = selectElement->GetOptions(getter_AddRefs(options)); } + + // Either use options and focused index, or default to list node itself + if (NS_SUCCEEDED(rv) && options && focusedOptionIndex >= 0) // Something is focused + rv = options->Item(focusedOptionIndex, getter_AddRefs(aFocusedOptionNode)); + else { // If no options in list or focusedOptionIndex <0, then we are not focused on an item + aFocusedOptionNode = aListNode; // return normal target content + rv = NS_OK; + } + return rv; } +/** ------------------------------------------------------ */ +/** Secondly, the Listbox widget */ +/** ------------------------------------------------------ */ + +/** ----- nsHTMLListboxAccessible ----- */ + +/** Constructor */ +nsHTMLListboxAccessible::nsHTMLListboxAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell): +nsListboxAccessible(aDOMNode, aShell) +{ +} + +/** Inherit the ISupports impl from nsAccessible, we handle nsIAccessibleSelectable */ +NS_IMPL_ISUPPORTS_INHERITED1(nsHTMLListboxAccessible, nsListboxAccessible, nsIAccessibleSelectable) + +/** + * Our last (and only) child is an nsHTMLSelectListAccessible object + */ +NS_IMETHODIMP nsHTMLListboxAccessible::GetAccLastChild(nsIAccessible **_retval) +{ + *_retval = new nsHTMLSelectListAccessible(this, mDOMNode, mPresShell); + if ( ! *_retval ) + return NS_ERROR_FAILURE; + NS_ADDREF(*_retval); + return NS_OK; +} + +/** + * Our first (and only) child is an nsHTMLSelectListAccessible object + */ +NS_IMETHODIMP nsHTMLListboxAccessible::GetAccFirstChild(nsIAccessible **_retval) +{ + *_retval = new nsHTMLSelectListAccessible(this, mDOMNode, mPresShell); + if ( ! *_retval ) + return NS_ERROR_FAILURE; + NS_ADDREF(*_retval); + return NS_OK; +} + +/** + * Our value is the value of our ( first ) selected child. nsIDOMHTMLSelectElement + * returns this by default with GetValue(). + */ +NS_IMETHODIMP nsHTMLListboxAccessible::GetAccValue(nsAWritableString& _retval) +{ + nsCOMPtr select (do_QueryInterface(mDOMNode)); + if ( select ) { + select->GetValue(_retval); + return NS_OK; + } + 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) +{ +} + +/** + * Our last child is an nsHTMLComboboxWindowAccessible object + */ +NS_IMETHODIMP nsHTMLComboboxAccessible::GetAccLastChild(nsIAccessible **_retval) +{ + *_retval = new nsHTMLComboboxWindowAccessible(this, mDOMNode, mPresShell); + if (! *_retval) + return NS_ERROR_FAILURE; + NS_ADDREF(*_retval); + return NS_OK; +} + +/** + * Our last child is an nsHTMLComboboxTextFieldAccessible object + */ +NS_IMETHODIMP nsHTMLComboboxAccessible::GetAccFirstChild(nsIAccessible **_retval) +{ + *_retval = new nsHTMLComboboxTextFieldAccessible(this, mDOMNode, mPresShell); + if (! *_retval) + return NS_ERROR_FAILURE; + NS_ADDREF(*_retval); + return NS_OK; +} + +/** + * Our value is the value of our ( first ) selected child. nsIDOMHTMLSelectElement + * returns this by default with GetValue(). + */ +NS_IMETHODIMP nsHTMLComboboxAccessible::GetAccValue(nsAWritableString& _retval) +{ + nsCOMPtr select (do_QueryInterface(mDOMNode)); + if (select) { + select->GetValue(_retval); + return NS_OK; + } + return NS_ERROR_FAILURE; +} + +/** ----- nsHTMLComboboxTextFieldAccessible ----- */ + +/** Constructor */ +nsHTMLComboboxTextFieldAccessible::nsHTMLComboboxTextFieldAccessible(nsIAccessible* aParent, + nsIDOMNode* aDOMNode, + nsIWeakReference* aShell): +nsComboboxTextFieldAccessible(aParent, aDOMNode, aShell) +{ +} + +/** + * Our next sibling is an nsHTMLComboboxButtonAccessible object + */ +NS_IMETHODIMP nsHTMLComboboxTextFieldAccessible::GetAccNextSibling(nsIAccessible **_retval) +{ + nsCOMPtr parent; + GetAccParent(getter_AddRefs(parent)); + + *_retval = new nsHTMLComboboxButtonAccessible(parent, mDOMNode, mPresShell); + if (! *_retval) + return NS_ERROR_FAILURE; + NS_ADDREF(*_retval); + return NS_OK; +} + +/** -----ComboboxButtonAccessible ----- */ + +/** Constructor -- cache our parent */ +nsHTMLComboboxButtonAccessible::nsHTMLComboboxButtonAccessible(nsIAccessible* aParent, + nsIDOMNode* aDOMNode, + nsIWeakReference* aShell): +nsComboboxButtonAccessible(aParent, aDOMNode, aShell) +{ +} + +/** + * Programmaticaly click on the button, causing either the display or + * the hiding of the drop down box ( window ). + * Walks the Frame tree and checks for proper frames. + */ +NS_IMETHODIMP nsHTMLComboboxButtonAccessible::AccDoAction(PRUint8 index) +{ + nsIFrame* frame = nsAccessible::GetBoundsFrame(); + nsCOMPtr context; + GetPresContext(context); + if (!context) + return NS_ERROR_FAILURE; + + frame->FirstChild(context, nsnull, &frame); +#ifdef DEBUG + if (! nsAccessible::IsCorrectFrameType(frame, nsLayoutAtoms::blockFrame)) + return NS_ERROR_FAILURE; +#endif + + frame->GetNextSibling(&frame); +#ifdef DEBUG + if (! nsAccessible::IsCorrectFrameType(frame, nsLayoutAtoms::gfxButtonControlFrame)) + return NS_ERROR_FAILURE; +#endif + + nsCOMPtr content; + frame->GetContent(getter_AddRefs(content)); + + // We only have one action, click. Any other index is meaningless(wrong) + if (index == eAction_Click) { + nsCOMPtr element(do_QueryInterface(content)); + if (element) + { + element->Click(); + return NS_OK; + } + return NS_ERROR_FAILURE; + } + return NS_ERROR_INVALID_ARG; +} + +/** + * Our next sibling is an nsHTMLComboboxWindowAccessible object + */ +NS_IMETHODIMP nsHTMLComboboxButtonAccessible::GetAccNextSibling(nsIAccessible **_retval) +{ + nsCOMPtr parent; + GetAccParent(getter_AddRefs(parent)); + + *_retval = new nsHTMLComboboxWindowAccessible(parent, mDOMNode, mPresShell); + if (! *_retval) + return NS_ERROR_OUT_OF_MEMORY; + NS_ADDREF(*_retval); + return NS_OK; +} + +/** + * Our next sibling is an nsHTMLComboboxTextFieldAccessible object + */ +NS_IMETHODIMP nsHTMLComboboxButtonAccessible::GetAccPreviousSibling(nsIAccessible **_retval) +{ + nsCOMPtr parent; + GetAccParent(getter_AddRefs(parent)); + + *_retval = new nsHTMLComboboxTextFieldAccessible(parent, mDOMNode, mPresShell); + if (! *_retval) + return NS_ERROR_FAILURE; + NS_ADDREF(*_retval); + return NS_OK; +} + +/** ----- nsHTMLComboboxWindowAccessible ----- */ + +/** + * Constructor -- cache our parent + */ +nsHTMLComboboxWindowAccessible::nsHTMLComboboxWindowAccessible(nsIAccessible* aParent, + nsIDOMNode* aDOMNode, + nsIWeakReference* aShell): +nsComboboxWindowAccessible(aParent, aDOMNode, aShell) +{ +} + +/** + * Our previous sibling is a nsHTMLComboboxButtonAccessible object + */ +NS_IMETHODIMP nsHTMLComboboxWindowAccessible::GetAccPreviousSibling(nsIAccessible **_retval) +{ + nsCOMPtr parent; + GetAccParent(getter_AddRefs(parent)); + + *_retval = new nsHTMLComboboxButtonAccessible(parent, mDOMNode, mPresShell); + if (! *_retval) + return NS_ERROR_FAILURE; + NS_ADDREF(*_retval); + return NS_OK; +} + +/** + * We only have one child, a list + */ +NS_IMETHODIMP nsHTMLComboboxWindowAccessible::GetAccLastChild(nsIAccessible **_retval) +{ + *_retval = new nsHTMLSelectListAccessible(this, mDOMNode, mPresShell); + if (! *_retval) + return NS_ERROR_FAILURE; + NS_ADDREF(*_retval); + return NS_OK; +} + +/** + * We only have one child, a list + */ +NS_IMETHODIMP nsHTMLComboboxWindowAccessible::GetAccFirstChild(nsIAccessible **_retval) +{ + *_retval = new nsHTMLSelectListAccessible(this, mDOMNode, mPresShell); + if (! *_retval) + return NS_ERROR_FAILURE; + NS_ADDREF(*_retval); + return NS_OK; +} + diff --git a/mozilla/accessible/src/html/nsHTMLSelectAccessible.h b/mozilla/accessible/src/html/nsHTMLSelectAccessible.h index 355abef2763..851c5edb044 100644 --- a/mozilla/accessible/src/html/nsHTMLSelectAccessible.h +++ b/mozilla/accessible/src/html/nsHTMLSelectAccessible.h @@ -39,49 +39,171 @@ #ifndef __nsHTMLSelectAccessible_h__ #define __nsHTMLSelectAccessible_h__ -#include "nsAccessible.h" #include "nsCOMPtr.h" -#include "nsIAtom.h" #include "nsIAccessibleSelectable.h" +#include "nsIDOMNode.h" +#include "nsIWeakReference.h" +#include "nsSelectAccessible.h" -class nsHTMLSelectAccessible : public nsAccessible, - public nsIAccessibleSelectable +/** + * Selects, Listboxes and Comboboxes, are made up of a number of different + * widgets, some of which are shared between the two. This file contains + * all of the widgets for both of the Selects, for HTML only. Some of them + * extend classes from nsSelectAccessible.cpp, which contains base classes + * that are also extended by the XUL Select Accessibility support. + * + * Listbox: + * - nsHTMLListboxAccessible + * - nsHTMLSelctListAccessible + * - nsHTMLSelectOptionAccessible + * + * Comboboxes: + * - nsHTMLComboboxAccessilbe + * - nsHTMLComboboxTextFieldAccessible + * - nsHTMLComboboxButtonAccessible + * - nsHTMLComboboxWindowAccessilbe + * - nsHTMLSelectListAccessible + * - nsHTMLSelectOptionAccessible(s) + */ + +/** ------------------------------------------------------ */ +/** First, the common widgets */ +/** ------------------------------------------------------ */ + +/* + * The list that contains all the options in the select. + */ +class nsHTMLSelectListAccessible : public nsSelectListAccessible +{ +public: + + nsHTMLSelectListAccessible(nsIAccessible* aParent, nsIDOMNode* aDOMNode, nsIWeakReference* aShell); + virtual ~nsHTMLSelectListAccessible() {} + + /* ----- nsIAccessible ----- */ + NS_IMETHOD GetAccState(PRUint32 *_retval); + NS_IMETHOD GetAccLastChild(nsIAccessible **_retval); + NS_IMETHOD GetAccFirstChild(nsIAccessible **_retval); + +}; + +/* + * Options inside the select, contained within the list + */ +class nsHTMLSelectOptionAccessible : public nsSelectOptionAccessible +{ +public: + + nsHTMLSelectOptionAccessible(nsIAccessible* aParent, nsIDOMNode* aDOMNode, nsIWeakReference* aShell); + virtual ~nsHTMLSelectOptionAccessible() {} + + /* ----- nsIAccessible ----- */ + NS_IMETHOD GetAccState(PRUint32 *_retval); + NS_IMETHOD GetAccNextSibling(nsIAccessible **_retval); + NS_IMETHOD GetAccPreviousSibling(nsIAccessible **_retval); + + static nsresult GetFocusedOptionNode(nsIWeakReference *aPresShell, nsIDOMNode *aListNode, nsCOMPtr& aFocusedOptionNode); + +}; + +/** ------------------------------------------------------ */ +/** Secondly, the Listbox widget */ +/** ------------------------------------------------------ */ + +/* + * A class the represents the HTML Listbox widget. + */ +class nsHTMLListboxAccessible : public nsListboxAccessible, + public nsIAccessibleSelectable { public: NS_DECL_ISUPPORTS_INHERITED NS_DECL_NSIACCESSIBLESELECTABLE - nsHTMLSelectAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell); - virtual ~nsHTMLSelectAccessible() {} + nsHTMLListboxAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell); + virtual ~nsHTMLListboxAccessible() {} + /* ----- nsIAccessible ----- */ NS_IMETHOD GetAccLastChild(nsIAccessible **_retval); NS_IMETHOD GetAccFirstChild(nsIAccessible **_retval); - NS_IMETHOD GetAccRole(PRUint32 *_retval); NS_IMETHOD GetAccValue(nsAWritableString& _retval); - NS_IMETHOD GetAccChildCount(PRInt32 *_retval); -// helper method to verify frames - static PRBool IsCorrectFrame( nsIFrame* aFrame, nsIAtom* aAtom ); +}; + +/** ------------------------------------------------------ */ +/** Finally, the Combobox widgets */ +/** ------------------------------------------------------ */ + +/* + * A class the represents the HTML Combobox widget. + */ +class nsHTMLComboboxAccessible : public nsComboboxAccessible +{ +public: + + nsHTMLComboboxAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell); + virtual ~nsHTMLComboboxAccessible() {} + + /* ----- nsIAccessible ----- */ + NS_IMETHOD GetAccLastChild(nsIAccessible **_retval); + NS_IMETHOD GetAccFirstChild(nsIAccessible **_retval); + NS_IMETHOD GetAccValue(nsAWritableString& _retval); }; /* - * Each option in the Select. These are in the nsListAccessible + * A class the represents the text field in the Select to the left + * of the drop down button */ -class nsHTMLSelectOptionAccessible : public nsLeafAccessible +class nsHTMLComboboxTextFieldAccessible : public nsComboboxTextFieldAccessible { public: - nsHTMLSelectOptionAccessible(nsIAccessible* aParent, nsIDOMNode* aDOMNode, nsIWeakReference* aShell); + nsHTMLComboboxTextFieldAccessible(nsIAccessible* aParent, nsIDOMNode* aDOMNode, nsIWeakReference* aShell); + virtual ~nsHTMLComboboxTextFieldAccessible() {} - NS_IMETHOD GetAccParent(nsIAccessible **_retval); - NS_IMETHOD GetAccRole(PRUint32 *_retval); + /* ----- nsIAccessible ----- */ NS_IMETHOD GetAccNextSibling(nsIAccessible **_retval); - NS_IMETHOD GetAccPreviousSibling(nsIAccessible **_retval); - NS_IMETHOD GetAccName(nsAWritableString& _retval); - nsCOMPtr mParent; }; +/** + * A class that represents the button inside the Select to the + * right of the text field + */ +class nsHTMLComboboxButtonAccessible : public nsComboboxButtonAccessible +{ +public: + + nsHTMLComboboxButtonAccessible(nsIAccessible* aParent, nsIDOMNode* aDOMNode, nsIWeakReference* aShell); + virtual ~nsHTMLComboboxButtonAccessible() {} + + /* ----- nsIAccessible ----- */ + NS_IMETHOD GetAccNextSibling(nsIAccessible **_retval); + NS_IMETHOD GetAccPreviousSibling(nsIAccessible **_retval); + NS_IMETHOD AccDoAction(PRUint8 index); + +}; + +/* + * A class that represents the window that lives to the right + * of the drop down button inside the Select. This is the window + * that is made visible when the button is pressed. + */ +class nsHTMLComboboxWindowAccessible : public nsComboboxWindowAccessible +{ +public: + + nsHTMLComboboxWindowAccessible(nsIAccessible* aParent, nsIDOMNode* aDOMNode, nsIWeakReference* aShell); + virtual ~nsHTMLComboboxWindowAccessible() {} + + /* ----- nsIAccessible ----- */ + NS_IMETHOD GetAccPreviousSibling(nsIAccessible **_retval); + NS_IMETHOD GetAccLastChild(nsIAccessible **_retval); + NS_IMETHOD GetAccFirstChild(nsIAccessible **_retval); + +}; + + #endif diff --git a/mozilla/accessible/src/html/nsHTMLTextAccessible.cpp b/mozilla/accessible/src/html/nsHTMLTextAccessible.cpp index b13dddb2960..85957af981c 100644 --- a/mozilla/accessible/src/html/nsHTMLTextAccessible.cpp +++ b/mozilla/accessible/src/html/nsHTMLTextAccessible.cpp @@ -38,16 +38,6 @@ * ***** END LICENSE BLOCK ***** */ #include "nsHTMLTextAccessible.h" -#include "nsWeakReference.h" -#include "nsIFrame.h" -#include "nsILink.h" -#include "nsILinkHandler.h" -#include "nsISelection.h" -#include "nsISelectionController.h" -#include "nsIPresContext.h" -#include "nsReadableUtils.h" -#include "nsIDOMXULDescriptionElement.h" -#include "nsIDOMXULLabelElement.h" nsHTMLTextAccessible::nsHTMLTextAccessible(nsIDOMNode* aDomNode, nsIWeakReference* aShell): nsTextAccessible(aDomNode, aShell) diff --git a/mozilla/accessible/src/html/nsHTMLTextAccessible.h b/mozilla/accessible/src/html/nsHTMLTextAccessible.h index 391689df547..cbd8ce226da 100644 --- a/mozilla/accessible/src/html/nsHTMLTextAccessible.h +++ b/mozilla/accessible/src/html/nsHTMLTextAccessible.h @@ -39,8 +39,7 @@ #ifndef _nsHTMLTextAccessible_H_ #define _nsHTMLTextAccessible_H_ -#include "nsAccessible.h" -#include "nsBaseWidgetAccessible.h" +#include "nsFormControlAccessible.h" class nsIWeakReference; diff --git a/mozilla/accessible/src/makefile.win b/mozilla/accessible/src/makefile.win index b2c41b9fdb7..79cd22ff95a 100644 --- a/mozilla/accessible/src/makefile.win +++ b/mozilla/accessible/src/makefile.win @@ -44,31 +44,31 @@ REQUIRES = xpcom \ timer \ $(NULL) -CPP_OBJS=\ - .\$(OBJDIR)\nsAccessible.obj \ - .\$(OBJDIR)\nsRootAccessible.obj \ - .\$(OBJDIR)\nsHTMLIFrameRootAccessible.obj \ - .\$(OBJDIR)\nsAccessibilityService.obj \ - .\$(OBJDIR)\nsHTMLSelectListAccessible.obj \ - .\$(OBJDIR)\nsGenericAccessible.obj \ - .\$(OBJDIR)\nsHTMLFormControlAccessible.obj \ - .\$(OBJDIR)\nsHTMLTextAccessible.obj \ - .\$(OBJDIR)\nsHTMLImageAccessible.obj \ - .\$(OBJDIR)\nsHTMLAreaAccessible.obj \ - .\$(OBJDIR)\nsHTMLTableAccessible.obj \ - .\$(OBJDIR)\nsHTMLLinkAccessible.obj \ - .\$(OBJDIR)\nsHTMLComboboxAccessible.obj \ - .\$(OBJDIR)\nsHTMLListboxAccessible.obj \ - .\$(OBJDIR)\nsXULFormControlAccessible.obj \ - .\$(OBJDIR)\nsXULTextAccessible.obj \ - .\$(OBJDIR)\nsBaseWidgetAccessible.obj \ +CPP_OBJS= \ + .\$(OBJDIR)\nsAccessible.obj \ + .\$(OBJDIR)\nsAccessibilityService.obj \ + .\$(OBJDIR)\nsBaseWidgetAccessible.obj \ + .\$(OBJDIR)\nsFormControlAccessible.obj \ + .\$(OBJDIR)\nsGenericAccessible.obj \ + .\$(OBJDIR)\nsHTMLAreaAccessible.obj \ + .\$(OBJDIR)\nsHTMLFormControlAccessible.obj \ + .\$(OBJDIR)\nsHTMLIFrameRootAccessible.obj \ + .\$(OBJDIR)\nsHTMLImageAccessible.obj \ + .\$(OBJDIR)\nsHTMLLinkAccessible.obj \ + .\$(OBJDIR)\nsHTMLSelectAccessible.obj \ + .\$(OBJDIR)\nsHTMLTableAccessible.obj \ + .\$(OBJDIR)\nsHTMLTextAccessible.obj \ + .\$(OBJDIR)\nsRootAccessible.obj \ + .\$(OBJDIR)\nsSelectAccessible.obj \ + .\$(OBJDIR)\nsXULFormControlAccessible.obj \ + .\$(OBJDIR)\nsXULTextAccessible.obj \ $(NULL) EXPORTS = \ .\nsRootAccessible.h \ $(NULL) -LINCS= \ +LINCS= \ -I..\..\layout\html\forms\public \ -I..\..\layout\html\forms\src \ -I..\..\layout\html\base\src \ diff --git a/mozilla/accessible/src/nsAccessibilityService.cpp b/mozilla/accessible/src/nsAccessibilityService.cpp index e351163a13c..b7069437458 100644 --- a/mozilla/accessible/src/nsAccessibilityService.cpp +++ b/mozilla/accessible/src/nsAccessibilityService.cpp @@ -57,9 +57,7 @@ #include "nsHTMLImageAccessible.h" #include "nsHTMLAreaAccessible.h" #include "nsHTMLLinkAccessible.h" -#include "nsHTMLSelectListAccessible.h" -#include "nsHTMLComboboxAccessible.h" -#include "nsHTMLListboxAccessible.h" +#include "nsHTMLSelectAccessible.h" #include "nsIDOMHTMLAreaElement.h" #include "nsHTMLFormControlAccessible.h" #include "nsIAccessibleProvider.h" @@ -76,7 +74,9 @@ #include "nsIDocShell.h" #include "nsHTMLIFrameRootAccessible.h" -//-------------------- +/** + * nsAccessibility Service + */ nsAccessibilityService::nsAccessibilityService() { @@ -89,9 +89,6 @@ nsAccessibilityService::~nsAccessibilityService() NS_IMPL_THREADSAFE_ISUPPORTS1(nsAccessibilityService, nsIAccessibilityService); - - - //////////////////////////////////////////////////////////////////////////////// // nsIAccessibilityService methods: @@ -322,7 +319,7 @@ NS_IMETHODIMP nsAccessibilityService::CreateXULTextAccessible(nsIDOMNode *aNode, // reusing the HTML accessible widget and enhancing for XUL *_retval = new nsXULTextAccessible(aNode, weakShell); - if (! *_retval) + if (! *_retval) return NS_ERROR_OUT_OF_MEMORY; NS_ADDREF(*_retval); @@ -595,7 +592,6 @@ nsAccessibilityService::CreateHTMLIFrameAccessible(nsIDOMNode* aDOMNode, nsISupp return NS_ERROR_FAILURE; } - void nsAccessibilityService::GetOwnerFor(nsIPresShell *aPresShell, nsIPresShell **aOwnerShell, nsIContent **aOwnerContent) { nsCOMPtr presContext; @@ -646,10 +642,9 @@ void nsAccessibilityService::GetOwnerFor(nsIPresShell *aPresShell, nsIPresShell } } -/* ------------------------------------------------------- - * GetAccessibleFor - get an nsIAccessible from a DOM node - * ------------------------------------------------------- */ - +/** + * GetAccessibleFor - get an nsIAccessible from a DOM node + */ NS_IMETHODIMP nsAccessibilityService::GetAccessibleFor(nsIDOMNode *aNode, nsIAccessible **_retval) { diff --git a/mozilla/accessible/src/nsAccessible.cpp b/mozilla/accessible/src/nsAccessible.cpp index 53b383f42b9..b832cd0ffee 100644 --- a/mozilla/accessible/src/nsAccessible.cpp +++ b/mozilla/accessible/src/nsAccessible.cpp @@ -80,6 +80,20 @@ #include "nsReadableUtils.h" #include "nsIBindingManager.h" +#include "nsFormControlAccessible.h" +#include "nsIDOMHTMLFormElement.h" +#include "nsIDOMHTMLInputElement.h" +#include "nsIDOMHTMLLabelElement.h" +#include "nsIDOMNodeList.h" +#include "nsIDOMXULButtonElement.h" +#include "nsIDOMXULCheckboxElement.h" +#include "nsIDOMXULDocument.h" +#include "nsIDOMXULElement.h" +#include "nsIDOMXULLabelElement.h" +#include "nsIDOMXULSelectCntrlEl.h" +#include "nsIDOMXULSelectCntrlItemEl.h" +#include "nsString.h" + // IFrame Helpers #include "nsIDocShell.h" #include "nsIWebShell.h" @@ -1324,3 +1338,194 @@ NS_IMETHODIMP nsAccessible::AppendFlatStringFromSubtree(nsIContent *aContent, ns } return NS_OK; } + +/** + * Called for XUL work only + * Checks the label's value first then makes a call to get the + * text from the children if the value is not set. + */ +NS_IMETHODIMP nsAccessible::AppendLabelText(nsIDOMNode *aLabelNode, nsAWritableString& _retval) +{ + NS_ASSERTION(aLabelNode, "Label Node passed in is null"); + nsCOMPtr labelNode(do_QueryInterface(aLabelNode)); + // label's value="foo" is set + if ( labelNode && NS_SUCCEEDED(labelNode->GetValue(_retval))) { + if (_retval.IsEmpty()) { + // label contains children who define it's text -- possibly HTML + nsCOMPtr content(do_QueryInterface(labelNode)); + if (content) + return AppendFlatStringFromSubtree(content, &_retval); + } + return NS_OK; + } + return NS_ERROR_FAILURE; +} + +/** + * Called for HTML work only + */ +NS_IMETHODIMP nsAccessible::AppendLabelFor(nsIContent *aLookNode, nsAReadableString *aId, nsAWritableString *aLabel) +{ + PRInt32 numChildren = 0; + + nsCOMPtr labelElement(do_QueryInterface(aLookNode)); + if (labelElement) { + nsCOMPtr elt(do_QueryInterface(aLookNode)); + nsresult rv = NS_OK; + + if (elt) { + nsAutoString labelIsFor; + elt->GetAttribute(NS_LITERAL_STRING("for"),labelIsFor); + if (labelIsFor.Equals(*aId)) + rv = AppendFlatStringFromSubtree(aLookNode, aLabel); + } + return rv; + } + + aLookNode->ChildCount(numChildren); + nsIContent *contentWalker; + PRInt32 index; + for (index = 0; index < numChildren; index++) { + aLookNode->ChildAt(index, contentWalker); + if (contentWalker) + AppendLabelFor(contentWalker, aId, aLabel); + } + return NS_OK; +} + +/** + * Only called if the element is not a nsIDOMXULControlElement. Initially walks up + * the DOM tree to the form, concatonating label elements as it goes. Then checks for + * labels with the for="controlID" property. + */ +NS_IMETHODIMP nsAccessible::GetHTMLAccName(nsAWritableString& _retval) +{ + nsCOMPtr walkUpContent(do_QueryInterface(mDOMNode)); + nsCOMPtr labelElement; + nsCOMPtr formElement; + nsresult rv = NS_OK; + + nsAutoString label; + // go up tree get name of ancestor label if there is one. Don't go up farther than form element + while (walkUpContent && label.IsEmpty() && !formElement) { + labelElement = do_QueryInterface(walkUpContent); + if (labelElement) + rv = AppendFlatStringFromSubtree(walkUpContent, &label); + formElement = do_QueryInterface(walkUpContent); // reached top ancestor in form + nsCOMPtr nextParent; + walkUpContent->GetParent(*getter_AddRefs(nextParent)); + walkUpContent = nextParent; + } + + + // There can be a label targeted at this control using the for="control_id" attribute + // To save computing time, only look for those inside of a form element + walkUpContent = do_QueryInterface(formElement); + + if (walkUpContent) { + nsCOMPtr elt(do_QueryInterface(mDOMNode)); + nsAutoString forId; + elt->GetAttribute(NS_LITERAL_STRING("id"), forId); + // Actually we'll be walking down the content this time, with a depth first search + if (!forId.IsEmpty()) + AppendLabelFor(walkUpContent,&forId,&label); + } + + label.CompressWhitespace(); + if (label.IsEmpty()) + return nsAccessible::GetAccName(_retval); + + _retval.Assign(label); + + return NS_OK; +} + +/** + * 3 main cases for XUL Controls to be labeled + * 1 - control contains label="foo" + * 2 - control has, as a child, a label element + * - label has either value="foo" or children + * 3 - non-child label contains control="controlID" + * - label has either value="foo" or children + * Once a label is found, the search is discontinued, so a control + * that has a label child as well as having a label external to + * the control that uses the control="controlID" syntax will use + * the child label for its Name. + */ +/* wstring getAccName (); */ +NS_IMETHODIMP nsAccessible::GetXULAccName(nsAWritableString& _retval) +{ + nsresult rv; + nsAutoString label; + + // CASE #1 -- great majority of the cases + nsCOMPtr domElement(do_QueryInterface(mDOMNode)); + NS_ASSERTION(domElement, "No domElement for accessible DOM node!"); + rv = domElement->GetAttribute(NS_LITERAL_STRING("label"), label) ; + + if (NS_FAILED(rv) || label.IsEmpty() ) { + + // CASE #2 ------ label as a child + nsCOMPtrlabelChildren; + NS_ASSERTION(domElement, "No domElement for accessible DOM node!"); + if (NS_SUCCEEDED(rv = domElement->GetElementsByTagName(NS_LITERAL_STRING("label"), getter_AddRefs(labelChildren)))) { + PRUint32 length = 0; + if (NS_SUCCEEDED(rv = labelChildren->GetLength(&length)) && length > 0) { + for (PRUint32 i = 0; i < length; ++i) { + nsCOMPtr child; + if (NS_SUCCEEDED(rv = labelChildren->Item(i, getter_AddRefs(child) ))) { + rv = AppendLabelText(child, label); + } + } + } + } + + if (NS_FAILED(rv) || label.IsEmpty()) { + + // CASE #3 ----- non-child label pointing to control + // XXX jgaunt + // decided to search the parent's children for labels linked to + // this control via the control="controlID" syntax, instead of searching + // the entire document with: + // + // nsCOMPtr doc; + // nsCOMPtr content(do_QueryInterface(mDOMNode)); + // content->GetDocument(*getter_AddRefs(doc)); + // nsCOMPtr xulDoc(do_QueryInterface(doc)); + // if (xulDoc) { + // nsCOMPtrlabelList; + // if (NS_SUCCEEDED(rv = xulDoc->GetElementsByAttribute(NS_LITERAL_STRING("control"), controlID, getter_AddRefs(labelList)))) + // + // This should keep search times down and still get the relevant + // labels. + nsCOMPtr parent; + if (NS_SUCCEEDED(rv = mDOMNode->GetParentNode(getter_AddRefs(parent)))) { + nsCOMPtr xulElement(do_QueryInterface(parent)); + NS_ASSERTION(xulElement, "No xulElement for parent DOM Node!"); + if (xulElement) { + nsAutoString controlID; + nsCOMPtrlabelList; + if (NS_SUCCEEDED(rv = xulElement->GetElementsByAttribute(NS_LITERAL_STRING("control"), controlID, getter_AddRefs(labelList)))) + { + PRUint32 length = 0; + if (NS_SUCCEEDED(rv = labelList->GetLength(&length)) && length > 0) { + for (PRUint32 i = 0; i < length; ++i) { + nsCOMPtr child; + if (NS_SUCCEEDED(rv = labelList->Item(i, getter_AddRefs(child) ))) { + rv = AppendLabelText(child, label); + } + } + } + } + } + } // End of CASE #3 + } // END of CASE #2 + } // END of CASE #1 + + label.CompressWhitespace(); + if (label.IsEmpty()) + return nsAccessible::GetAccName(_retval); + + _retval.Assign(label); + return NS_OK; +} diff --git a/mozilla/accessible/src/nsAccessible.h b/mozilla/accessible/src/nsAccessible.h index 44ed93d349f..295416705a3 100644 --- a/mozilla/accessible/src/nsAccessible.h +++ b/mozilla/accessible/src/nsAccessible.h @@ -65,6 +65,12 @@ enum { eSiblingsUninitialized = -1, eSiblingsWalkNormalDOM = -2}; // Used in si class nsAccessible : public nsGenericAccessible { public: + + // to eliminate the confusion of "magic numbers" -- if ( 0 ){ foo; } + enum { eAction_Switch=0, eAction_Jump=0, eAction_Click=0 }; + // how many actions + enum { eNo_Action=0, eSingle_Action=1 }; + NS_IMETHOD GetAccName(nsAWritableString& _retval); NS_IMETHOD GetAccParent(nsIAccessible **_retval); NS_IMETHOD GetAccNextSibling(nsIAccessible **_retval); @@ -116,6 +122,12 @@ public: // helper method to verify frames static PRBool IsCorrectFrameType(nsIFrame* aFrame, nsIAtom* aAtom); +protected: + NS_IMETHOD AppendLabelText(nsIDOMNode *aLabelNode, nsAWritableString& _retval); + NS_IMETHOD AppendLabelFor(nsIContent *aLookNode, nsAReadableString *aId, nsAWritableString *aLabel); + NS_IMETHOD GetHTMLAccName(nsAWritableString& _retval); + NS_IMETHOD GetXULAccName(nsAWritableString& _retval); + protected: virtual nsIFrame* GetFrame(); virtual nsIFrame* GetBoundsFrame(); diff --git a/mozilla/accessible/src/nsBaseWidgetAccessible.cpp b/mozilla/accessible/src/nsBaseWidgetAccessible.cpp index df55a527ba9..4fb07be2ad7 100644 --- a/mozilla/accessible/src/nsBaseWidgetAccessible.cpp +++ b/mozilla/accessible/src/nsBaseWidgetAccessible.cpp @@ -43,6 +43,7 @@ #include "nsGUIEvent.h" #include "nsIContent.h" #include "nsIDOMElement.h" +#include "nsIDOMEventReceiver.h" #include "nsIFrame.h" #include "nsILink.h" #include "nsIPresContext.h" @@ -113,6 +114,53 @@ NS_IMETHODIMP nsBlockAccessible::AccGetAt(PRInt32 tx, PRInt32 ty, nsIAccessible return NS_OK; } +/** + * nsContainerAccessible + */ +nsContainerAccessible::nsContainerAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell): +nsAccessible(aNode, aShell) +{ +} + +/** no actions */ +NS_IMETHODIMP nsContainerAccessible::GetAccNumActions(PRUint8 *_retval) +{ + *_retval = eNo_Action; + return NS_OK; +} + +/** no actions */ +NS_IMETHODIMP nsContainerAccessible::GetAccActionName(PRUint8 index, nsAWritableString& _retval) +{ + return NS_OK; +} + +/** no actions */ +NS_IMETHODIMP nsContainerAccessible::AccDoAction(PRUint8 index) +{ + return NS_OK; +} + +/** no state -- normal */ +NS_IMETHODIMP nsContainerAccessible::GetAccState(PRUint32 *_retval) +{ + *_retval = 0; + return NS_OK; +} + +/** no value */ +NS_IMETHODIMP nsContainerAccessible::GetAccValue(nsAWritableString& _retval) +{ + return NS_OK; +} + +/** no name*/ +NS_IMETHODIMP nsContainerAccessible::GetAccName(nsAWritableString& _retval) +{ + return NS_OK; +} + + //------------- // nsLeafFrameAccessible //------------- @@ -209,7 +257,7 @@ NS_IMETHODIMP nsLinkableAccessible::GetAccValue(nsAWritableString& _retval) /* PRUint8 getAccNumActions (); */ NS_IMETHODIMP nsLinkableAccessible::GetAccNumActions(PRUint8 *_retval) { - *_retval = 1; + *_retval = eSingle_Action; return NS_OK; } @@ -217,7 +265,7 @@ NS_IMETHODIMP nsLinkableAccessible::GetAccNumActions(PRUint8 *_retval) NS_IMETHODIMP nsLinkableAccessible::GetAccActionName(PRUint8 index, nsAWritableString& _retval) { // Action 0 (default action): Jump to link - if (index == 0) { + if (index == eAction_Jump) { if (IsALink()) { _retval = NS_LITERAL_STRING("jump"); return NS_OK; @@ -292,39 +340,71 @@ PRBool nsLinkableAccessible::IsALink() } // ------------ -// Text Accessibles +// nsMenuListenerAccessible // ------------ -nsTextAccessible::nsTextAccessible(nsIDOMNode* aDomNode, nsIWeakReference* aShell): -nsLinkableAccessible(aDomNode, aShell) +NS_IMPL_ISUPPORTS_INHERITED1(nsMenuListenerAccessible, nsAccessible, nsIDOMXULListener) + +nsMenuListenerAccessible::nsMenuListenerAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell): +nsAccessible(aDOMNode, aShell) +{ + mRegistered = PR_FALSE; + mOpen = PR_FALSE; +} + +nsMenuListenerAccessible::~nsMenuListenerAccessible() +{ + if (mRegistered) { + nsCOMPtr eventReceiver(do_QueryInterface(mDOMNode)); + if (eventReceiver) + eventReceiver->RemoveEventListener(NS_LITERAL_STRING("popupshowing"), this, PR_TRUE); + } +} + +NS_IMETHODIMP nsMenuListenerAccessible::PopupShowing(nsIDOMEvent* aEvent) { + mOpen = PR_TRUE; + + /* TBD send state change event */ + + return NS_OK; } -/* unsigned long getAccRole (); */ -NS_IMETHODIMP nsTextAccessible::GetAccRole(PRUint32 *_retval) +NS_IMETHODIMP nsMenuListenerAccessible::PopupHiding(nsIDOMEvent* aEvent) +{ + mOpen = PR_FALSE; + + /* TBD send state change event */ + + return NS_OK; +} + +NS_IMETHODIMP nsMenuListenerAccessible::Close(nsIDOMEvent* aEvent) +{ + mOpen = PR_FALSE; + + /* TBD send state change event */ + + return NS_OK; +} + +void +nsMenuListenerAccessible::SetupMenuListener() { - *_retval = ROLE_TEXT; + // if not already one, register ourselves as a popup listener + if (!mRegistered) { + nsCOMPtr eventReceiver(do_QueryInterface(mDOMNode)); + if (!eventReceiver) { + return; + } - return NS_OK; + nsresult rv = eventReceiver->AddEventListener(NS_LITERAL_STRING("popupshowing"), this, PR_TRUE); + + if (NS_FAILED(rv)) { + return; + } + + mRegistered = PR_TRUE; + } } -/* nsIAccessible getAccFirstChild (); */ -NS_IMETHODIMP nsTextAccessible::GetAccFirstChild(nsIAccessible **_retval) -{ - *_retval = nsnull; - return NS_OK; -} - -/* nsIAccessible getAccLastChild (); */ -NS_IMETHODIMP nsTextAccessible::GetAccLastChild(nsIAccessible **_retval) -{ - *_retval = nsnull; - return NS_OK; -} - -/* long getAccChildCount (); */ -NS_IMETHODIMP nsTextAccessible::GetAccChildCount(PRInt32 *_retval) -{ - *_retval = 0; - return NS_OK; -} diff --git a/mozilla/accessible/src/nsBaseWidgetAccessible.h b/mozilla/accessible/src/nsBaseWidgetAccessible.h index 106ce5d2a0e..5b4162aeb9f 100644 --- a/mozilla/accessible/src/nsBaseWidgetAccessible.h +++ b/mozilla/accessible/src/nsBaseWidgetAccessible.h @@ -41,9 +41,10 @@ #define _nsBaseWidgetAccessible_H_ #include "nsAccessible.h" -#include "nsIDOMNode.h" #include "nsCOMPtr.h" #include "nsIContent.h" +#include "nsIDOMNode.h" +#include "nsIDOMXULListener.h" /** * This file contains a number of classes that are used as base @@ -57,8 +58,24 @@ class nsBlockAccessible : public nsAccessible { public: - nsBlockAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell); - NS_IMETHOD AccGetAt(PRInt32 x, PRInt32 y, nsIAccessible **_retval); + nsBlockAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell); + NS_IMETHOD AccGetAt(PRInt32 x, PRInt32 y, nsIAccessible **_retval); +}; + +/** + * Special Accessible that just contains other accessible objects + * no actions, no name, no state, no value + */ +class nsContainerAccessible : public nsAccessible +{ +public: + nsContainerAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell); + NS_IMETHOD GetAccNumActions(PRUint8 *_retval); + NS_IMETHOD GetAccActionName(PRUint8 index, nsAWritableString& _retval); + NS_IMETHOD AccDoAction(PRUint8 index); + NS_IMETHOD GetAccState(PRUint32 *_retval); + NS_IMETHOD GetAccValue(nsAWritableString& _retval); + NS_IMETHOD GetAccName(nsAWritableString& _retval); }; /** @@ -66,12 +83,11 @@ public: */ class nsLeafAccessible : public nsAccessible { - public: - nsLeafAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell); - - NS_IMETHOD GetAccFirstChild(nsIAccessible **_retval); - NS_IMETHOD GetAccLastChild(nsIAccessible **_retval); - NS_IMETHOD GetAccChildCount(PRInt32 *_retval); +public: + nsLeafAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell); + NS_IMETHOD GetAccFirstChild(nsIAccessible **_retval); + NS_IMETHOD GetAccLastChild(nsIAccessible **_retval); + NS_IMETHOD GetAccChildCount(PRInt32 *_retval); }; /** @@ -81,36 +97,52 @@ class nsLeafAccessible : public nsAccessible */ class nsLinkableAccessible : public nsAccessible { - public: - nsLinkableAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell); - NS_IMETHOD GetAccNumActions(PRUint8 *_retval); - NS_IMETHOD GetAccActionName(PRUint8 index, nsAWritableString& _retval); - NS_IMETHOD AccDoAction(PRUint8 index); - NS_IMETHOD GetAccState(PRUint32 *_retval); - NS_IMETHOD GetAccValue(nsAWritableString& _retval); - - protected: - PRBool IsALink(); - PRBool mIsALinkCached; // -1 = unknown, 0 = not a link, 1 = is a link - nsCOMPtr mLinkContent; - PRBool mIsLinkVisited; -}; - -/** - * Text nodes have no children, but since double inheritance - * no-worky we have to re-impl the LeafAccessiblity blocks - * this way. - */ -class nsTextAccessible : public nsLinkableAccessible -{ - public: - nsTextAccessible(nsIDOMNode* aDomNode, nsIWeakReference* aShell); - NS_IMETHOD GetAccRole(PRUint32 *_retval); - NS_IMETHOD GetAccFirstChild(nsIAccessible **_retval); - NS_IMETHOD GetAccLastChild(nsIAccessible **_retval); - NS_IMETHOD GetAccChildCount(PRInt32 *_retval); + nsLinkableAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell); + NS_IMETHOD GetAccNumActions(PRUint8 *_retval); + NS_IMETHOD GetAccActionName(PRUint8 index, nsAWritableString& _retval); + NS_IMETHOD AccDoAction(PRUint8 index); + NS_IMETHOD GetAccState(PRUint32 *_retval); + NS_IMETHOD GetAccValue(nsAWritableString& _retval); + +protected: + PRBool IsALink(); + PRBool mIsALinkCached; // -1 = unknown, 0 = not a link, 1 = is a link + nsCOMPtr mLinkContent; + PRBool mIsLinkVisited; }; +/* + * A base class that can listen to menu events. Its used by selects so the + * button and the window accessibles can change their name and role + * depending on whether the drop down list is dropped down on not + */ +class nsMenuListenerAccessible : public nsAccessible, public nsIDOMXULListener +{ +public: + + NS_DECL_ISUPPORTS_INHERITED + + nsMenuListenerAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell); + virtual ~nsMenuListenerAccessible(); + + // popup listener + 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(); + + PRBool mRegistered; + PRBool mOpen; +}; #endif + diff --git a/mozilla/accessible/src/nsFormControlAccessible.cpp b/mozilla/accessible/src/nsFormControlAccessible.cpp new file mode 100644 index 00000000000..a345ba58d83 --- /dev/null +++ b/mozilla/accessible/src/nsFormControlAccessible.cpp @@ -0,0 +1,226 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: NPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Netscape 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/NPL/ + * + * 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): + * John Gaunt (jgaunt@netscape.com) + * Aaron Leventhal (aaronl@netscape.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 + * 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 NPL, 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 NPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +// NOTE: alphabetically ordered +#include "nsFormControlAccessible.h" +#include "nsIDocument.h" +#include "nsIDOMHTMLFormElement.h" +#include "nsIDOMHTMLInputElement.h" +#include "nsIDOMHTMLLabelElement.h" +#include "nsIDOMNodeList.h" +#include "nsIDOMXULButtonElement.h" +#include "nsIDOMXULCheckboxElement.h" +#include "nsIDOMXULDocument.h" +#include "nsIDOMXULElement.h" +#include "nsIDOMXULLabelElement.h" +#include "nsIDOMXULSelectCntrlEl.h" +#include "nsIDOMXULSelectCntrlItemEl.h" +#include "nsReadableUtils.h" +#include "nsString.h" + +/** + * nsFormControlAccessible + */ + +nsFormControlAccessible::nsFormControlAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell): +nsAccessible(aNode, aShell) +{ +} + +/** + * XUL states: focused, unavailable(disabled), focusable, ?protected? + * HTML states: focused, unabailable(disabled), focusable, protected + */ +NS_IMETHODIMP nsFormControlAccessible::GetAccState(PRUint32 *_retval) +{ + // Get the focused state from the nsAccessible + nsAccessible::GetAccState(_retval); + + PRBool disabled = PR_FALSE; + nsresult rv = NS_ERROR_FAILURE; + nsCOMPtr htmlFormElement(do_QueryInterface(mDOMNode, &rv)); + if (NS_SUCCEEDED(rv) && htmlFormElement) { + htmlFormElement->GetDisabled(&disabled); + nsAutoString typeString; + htmlFormElement->GetType(typeString); + if (typeString.EqualsIgnoreCase("password")) + *_retval |= STATE_PROTECTED; + } + else { + nsCOMPtr xulFormElement(do_QueryInterface(mDOMNode, &rv)); + if (NS_SUCCEEDED(rv) && xulFormElement) { + xulFormElement->GetDisabled(&disabled); + /* XXX jgaunt do XUL elements support password fields? */ + } + } + if (disabled) + *_retval |= STATE_UNAVAILABLE; + else + *_retval |= STATE_FOCUSABLE; + + return NS_OK; +} + +/** + * Will be called by both HTML and XUL elements, this method + * merely checks who is calling and then calls the appropriate + * protected method for the XUL or HTML element. + */ +NS_IMETHODIMP nsFormControlAccessible::GetAccName(nsAWritableString& _retval) +{ + nsCOMPtr xulFormElement(do_QueryInterface(mDOMNode)); + if (xulFormElement) + return GetXULAccName(_retval); + else + return GetHTMLAccName(_retval); +} + +/** + * No Children + */ +NS_IMETHODIMP nsFormControlAccessible::GetAccFirstChild(nsIAccessible **_retval) +{ + *_retval = nsnull; + return NS_OK; +} + +/** + * No Children + */ +NS_IMETHODIMP nsFormControlAccessible::GetAccLastChild(nsIAccessible **_retval) +{ + *_retval = nsnull; + return NS_OK; +} + +/** + * No Children + */ +NS_IMETHODIMP nsFormControlAccessible::GetAccChildCount(PRInt32 *_retval) +{ + *_retval = 0; + return NS_OK; +} + +// ------------ +// Radio button +// ------------ + +nsRadioButtonAccessible::nsRadioButtonAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell): +nsFormControlAccessible(aNode, aShell) +{ +} + +/** + * + */ +NS_IMETHODIMP nsRadioButtonAccessible::GetAccNumActions(PRUint8 *_retval) +{ + *_retval = eSingle_Action; + return NS_OK; +} + +/** + * + */ +NS_IMETHODIMP nsRadioButtonAccessible::GetAccActionName(PRUint8 index, nsAWritableString& _retval) +{ + if (index == eAction_Click) { + _retval = NS_LITERAL_STRING("select"); + return NS_OK; + } + return NS_ERROR_INVALID_ARG; +} + +/** + * + */ +NS_IMETHODIMP nsRadioButtonAccessible::GetAccRole(PRUint32 *_retval) +{ + *_retval = ROLE_RADIOBUTTON; + + return NS_OK; +} + +// ------------ +// Text Accessibles +// ------------ + +nsTextAccessible::nsTextAccessible(nsIDOMNode* aDomNode, nsIWeakReference* aShell): +nsLinkableAccessible(aDomNode, aShell) +{ +} + +/** + * We are text + */ +NS_IMETHODIMP nsTextAccessible::GetAccRole(PRUint32 *_retval) +{ + *_retval = ROLE_TEXT; + + return NS_OK; +} + +/** + * No Children + */ +NS_IMETHODIMP nsTextAccessible::GetAccFirstChild(nsIAccessible **_retval) +{ + *_retval = nsnull; + return NS_OK; +} + +/** + * No Children + */ +NS_IMETHODIMP nsTextAccessible::GetAccLastChild(nsIAccessible **_retval) +{ + *_retval = nsnull; + return NS_OK; +} + +/** + * No Children + */ +NS_IMETHODIMP nsTextAccessible::GetAccChildCount(PRInt32 *_retval) +{ + *_retval = 0; + return NS_OK; +} + diff --git a/mozilla/accessible/src/nsHTMLSelectListAccessible.h b/mozilla/accessible/src/nsFormControlAccessible.h similarity index 52% rename from mozilla/accessible/src/nsHTMLSelectListAccessible.h rename to mozilla/accessible/src/nsFormControlAccessible.h index 422dce04cc3..cd4ed5ff34a 100644 --- a/mozilla/accessible/src/nsHTMLSelectListAccessible.h +++ b/mozilla/accessible/src/nsFormControlAccessible.h @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* ***** BEGIN LICENSE BLOCK ***** * Version: NPL 1.1/GPL 2.0/LGPL 2.1 * @@ -20,7 +20,7 @@ * the Initial Developer. All Rights Reserved. * * Contributor(s): - * Original Author: Eric Vaughan (evaughan@netscape.com) + * Author: Eric D Vaughan (evaughan@netscape.com) * * * Alternatively, the contents of this file may be used under the terms of @@ -36,60 +36,58 @@ * the terms of any one of the NPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ -#ifndef __nsHTMLSelectListAccessible_h__ -#define __nsHTMLSelectListAccessible_h__ -#include "nsAccessible.h" +#ifndef _nsFormControlAccessible_H_ +#define _nsFormControlAccessible_H_ + #include "nsBaseWidgetAccessible.h" -#include "nsCOMPtr.h" - -/* - * The list that contains all the options in the select. - */ -class nsHTMLSelectListAccessible : public nsAccessible +/** + * This supports name and state information for both XUL and HTML + * widgets. Designed to be a base class for the impls of XUL + * and HTML form widget Accessibles + */ +class nsFormControlAccessible : public nsAccessible { public: - - nsHTMLSelectListAccessible(nsIAccessible* aParent, nsIDOMNode* aDOMNode, nsIWeakReference* aShell); - virtual ~nsHTMLSelectListAccessible() {} - - /* ----- nsIAccessible ----- */ - NS_IMETHOD GetAccParent(nsIAccessible **_retval); - NS_IMETHOD GetAccRole(PRUint32 *_retval); - NS_IMETHOD GetAccNextSibling(nsIAccessible **_retval); - NS_IMETHOD GetAccPreviousSibling(nsIAccessible **_retval); - NS_IMETHOD AccGetBounds(PRInt32 *x, PRInt32 *y, PRInt32 *width, PRInt32 *height); - NS_IMETHOD GetAccLastChild(nsIAccessible **_retval); + nsFormControlAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell); + NS_IMETHOD GetAccName(nsAWritableString& _retval); + NS_IMETHOD GetAccState(PRUint32 *_retval); NS_IMETHOD GetAccFirstChild(nsIAccessible **_retval); - NS_IMETHOD GetAccState(PRUint32 *_retval); + NS_IMETHOD GetAccLastChild(nsIAccessible **_retval); + NS_IMETHOD GetAccChildCount(PRInt32 *_retval); -protected: - - nsCOMPtr mParent; }; -/* - * Options inside the select, contained within the list - */ -class nsHTMLSelectOptionAccessible : public nsLeafAccessible +/** + * + */ +class nsRadioButtonAccessible : public nsFormControlAccessible { + public: - - nsHTMLSelectOptionAccessible(nsIAccessible* aParent, nsIDOMNode* aDOMNode, nsIWeakReference* aShell); - - /* ----- nsIAccessible ----- */ - NS_IMETHOD GetAccParent(nsIAccessible **_retval); - NS_IMETHOD GetAccRole(PRUint32 *_retval); - NS_IMETHOD GetAccNextSibling(nsIAccessible **_retval); - NS_IMETHOD GetAccPreviousSibling(nsIAccessible **_retval); - NS_IMETHOD GetAccName(nsAWritableString& _retval); - NS_IMETHOD GetAccState(PRUint32 *_retval); - static nsresult GetFocusedOptionNode(nsIWeakReference *aPresShell, nsIDOMNode *aListNode, nsCOMPtr& aFocusedOptionNode); - -protected: - - nsCOMPtr mParent; + nsRadioButtonAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell); + NS_IMETHOD GetAccRole(PRUint32 *_retval); + NS_IMETHOD GetAccNumActions(PRUint8 *_retval); + NS_IMETHOD GetAccActionName(PRUint8 index, nsAWritableString& _retval); }; +/** + * Text nodes have no children, but since double inheritance + * no-worky we have to re-impl the LeafAccessiblity blocks + * this way. + */ +class nsTextAccessible : public nsLinkableAccessible +{ + +public: + nsTextAccessible(nsIDOMNode* aDomNode, nsIWeakReference* aShell); + NS_IMETHOD GetAccRole(PRUint32 *_retval); + NS_IMETHOD GetAccFirstChild(nsIAccessible **_retval); + NS_IMETHOD GetAccLastChild(nsIAccessible **_retval); + NS_IMETHOD GetAccChildCount(PRInt32 *_retval); +}; + + #endif + diff --git a/mozilla/accessible/src/nsHTMLFormControlAccessible.cpp b/mozilla/accessible/src/nsHTMLFormControlAccessible.cpp index 164eea15c29..deb534beab3 100644 --- a/mozilla/accessible/src/nsHTMLFormControlAccessible.cpp +++ b/mozilla/accessible/src/nsHTMLFormControlAccessible.cpp @@ -37,150 +37,48 @@ * * ***** END LICENSE BLOCK ***** */ -#include "nsHTMLFormControlAccessible.h" -#include "nsWeakReference.h" -#include "nsIDOMHTMLInputElement.h" -#include "nsIDOMHTMLTextAreaElement.h" -#include "nsINameSpaceManager.h" -#include "nsHTMLAtoms.h" -#include "nsIDOMHTMLButtonElement.h" -#include "nsReadableUtils.h" +// NOTE: alphabetically ordered #include "nsAccessible.h" -#include "nsIFrame.h" -#include "nsIDOMHTMLLabelElement.h" +#include "nsFormControlAccessible.h" +#include "nsHTMLAtoms.h" +#include "nsHTMLFormControlAccessible.h" +#include "nsIDOMHTMLButtonElement.h" #include "nsIDOMHTMLFormElement.h" -#include "nsISelectionController.h" +#include "nsIDOMHTMLInputElement.h" +#include "nsIDOMHTMLLabelElement.h" +#include "nsIDOMHTMLTextAreaElement.h" #include "nsIDOMXULCheckboxElement.h" #include "nsIDOMXULButtonElement.h" - -nsHTMLFormControlAccessible::nsHTMLFormControlAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell): -nsLeafAccessible(aNode, aShell) -{ -} - -NS_IMETHODIMP nsHTMLFormControlAccessible::AppendLabelFor(nsIContent *aLookNode, nsAReadableString *aId, nsAWritableString *aLabel) -{ - PRInt32 numChildren = 0; - - nsCOMPtr labelElement(do_QueryInterface(aLookNode)); - if (labelElement) { - nsCOMPtr elt(do_QueryInterface(aLookNode)); - nsresult rv = NS_OK; - - if (elt) { - nsAutoString labelIsFor; - elt->GetAttribute(NS_LITERAL_STRING("for"),labelIsFor); - if (labelIsFor.Equals(*aId)) - rv = AppendFlatStringFromSubtree(aLookNode, aLabel); - } - return rv; - } - - aLookNode->ChildCount(numChildren); - nsIContent *contentWalker; - PRInt32 index; - for (index = 0; index < numChildren; index++) { - aLookNode->ChildAt(index, contentWalker); - if (contentWalker) - AppendLabelFor(contentWalker, aId, aLabel); - } - return NS_OK; -} - -/* wstring getAccName (); */ -NS_IMETHODIMP nsHTMLFormControlAccessible::GetAccName(nsAWritableString& _retval) -{ - nsCOMPtr walkUpContent(do_QueryInterface(mDOMNode)); - nsCOMPtr labelElement; - nsCOMPtr formElement; - nsresult rv = NS_OK; - - nsAutoString label; - // go up tree get name of ancestor label if there is one. Don't go up farther than form element - while (walkUpContent && label.IsEmpty() && !formElement) { - labelElement = do_QueryInterface(walkUpContent); - if (labelElement) - rv = AppendFlatStringFromSubtree(walkUpContent, &label); - formElement = do_QueryInterface(walkUpContent); // reached top ancestor in form - nsCOMPtr nextParent; - walkUpContent->GetParent(*getter_AddRefs(nextParent)); - walkUpContent = nextParent; - } - - - // There can be a label targeted at this control using the for="control_id" attribute - // To save computing time, only look for those inside of a form element - walkUpContent = do_QueryInterface(formElement); - - if (walkUpContent) { - nsCOMPtr elt(do_QueryInterface(mDOMNode)); - nsAutoString forId; - elt->GetAttribute(NS_LITERAL_STRING("id"), forId); - // Actually we'll be walking down the content this time, with a depth first search - if (!forId.IsEmpty()) - AppendLabelFor(walkUpContent,&forId,&label); - } - - label.CompressWhitespace(); - if (label.IsEmpty()) - return nsAccessible::GetAccName(_retval); - - _retval.Assign(label); - - return NS_OK; -} - -/* long getAccState (); */ -NS_IMETHODIMP nsHTMLFormControlAccessible::GetAccState(PRUint32 *_retval) -{ - // can be - // focusable, focused, protected, unavailable - nsCOMPtr htmlFormElement(do_QueryInterface(mDOMNode)); - - nsAccessible::GetAccState(_retval); - - PRBool disabled = PR_FALSE; - if (htmlFormElement) { - htmlFormElement->GetDisabled(&disabled); - nsAutoString typeString; - htmlFormElement->GetType(typeString); - if (typeString.EqualsIgnoreCase("password")) - *_retval |= STATE_PROTECTED; - } - - if (disabled) - *_retval |= STATE_UNAVAILABLE; - else - *_retval |= STATE_FOCUSABLE; - - return NS_OK; -} +#include "nsIDOMXULSelectCntrlItemEl.h" +#include "nsIDOMXULSelectCntrlEl.h" +#include "nsINameSpaceManager.h" +#include "nsIFrame.h" +#include "nsISelectionController.h" +#include "nsReadableUtils.h" +#include "nsWeakReference.h" // --- checkbox ----- nsHTMLCheckboxAccessible::nsHTMLCheckboxAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell): -nsHTMLFormControlAccessible(aNode, aShell) +nsFormControlAccessible(aNode, aShell) { } -/* unsigned long getAccRole (); */ NS_IMETHODIMP nsHTMLCheckboxAccessible::GetAccRole(PRUint32 *_retval) { *_retval = ROLE_CHECKBUTTON; return NS_OK; } -/* PRUint8 getAccNumActions (); */ NS_IMETHODIMP nsHTMLCheckboxAccessible::GetAccNumActions(PRUint8 *_retval) { - *_retval = 1; + *_retval = eSingle_Action; return NS_OK; } -/* wstring getAccActionName (in PRUint8 index); */ NS_IMETHODIMP nsHTMLCheckboxAccessible::GetAccActionName(PRUint8 index, nsAWritableString& _retval) { - if (index == 0) { // 0 is the magic value for default action + if (index == eAction_Click) { // 0 is the magic value for default action // check or uncheck PRUint32 state; GetAccState(&state); @@ -195,7 +93,6 @@ NS_IMETHODIMP nsHTMLCheckboxAccessible::GetAccActionName(PRUint8 index, nsAWrita return NS_ERROR_INVALID_ARG; } -/* void accDoAction (in PRUint8 index); */ NS_IMETHODIMP nsHTMLCheckboxAccessible::AccDoAction(PRUint8 index) { if (index == 0) { // 0 is the magic value for default action @@ -213,7 +110,7 @@ NS_IMETHODIMP nsHTMLCheckboxAccessible::AccDoAction(PRUint8 index) NS_IMETHODIMP nsHTMLCheckboxAccessible::GetAccState(PRUint32 *_retval) { - nsHTMLFormControlAccessible::GetAccState(_retval); + nsFormControlAccessible::GetAccState(_retval); PRBool checked = PR_FALSE; // Radio buttons and check boxes can be checked nsCOMPtr htmlCheckboxElement(do_QueryInterface(mDOMNode)); @@ -229,31 +126,13 @@ NS_IMETHODIMP nsHTMLCheckboxAccessible::GetAccState(PRUint32 *_retval) //------ Radio button ------- nsHTMLRadioButtonAccessible::nsHTMLRadioButtonAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell): -nsHTMLFormControlAccessible(aNode, aShell) +nsRadioButtonAccessible(aNode, aShell) { } -/* PRUint8 getAccNumActions (); */ -NS_IMETHODIMP nsHTMLRadioButtonAccessible::GetAccNumActions(PRUint8 *_retval) -{ - *_retval = 1; - return NS_OK; -} - -/* wstring getAccActionName (in PRUint8 index); */ -NS_IMETHODIMP nsHTMLRadioButtonAccessible::GetAccActionName(PRUint8 index, nsAWritableString& _retval) -{ - if (index == 0) { - _retval = NS_LITERAL_STRING("select"); - return NS_OK; - } - return NS_ERROR_INVALID_ARG; -} - -/* void accDoAction (in PRUint8 index); */ NS_IMETHODIMP nsHTMLRadioButtonAccessible::AccDoAction(PRUint8 index) { - if (index == 0) { + if (index == eAction_Click) { nsCOMPtr element(do_QueryInterface(mDOMNode)); element->Click(); return NS_OK; @@ -261,31 +140,15 @@ NS_IMETHODIMP nsHTMLRadioButtonAccessible::AccDoAction(PRUint8 index) return NS_ERROR_INVALID_ARG; } - -/* unsigned long getAccRole (); */ -NS_IMETHODIMP nsHTMLRadioButtonAccessible::GetAccRole(PRUint32 *_retval) -{ - *_retval = ROLE_RADIOBUTTON; - - return NS_OK; -} - NS_IMETHODIMP nsHTMLRadioButtonAccessible::GetAccState(PRUint32 *_retval) { - nsHTMLFormControlAccessible::GetAccState(_retval); + nsFormControlAccessible::GetAccState(_retval); PRBool checked = PR_FALSE; // Radio buttons and check boxes can be checked nsCOMPtr htmlRadioElement(do_QueryInterface(mDOMNode)); if (htmlRadioElement) htmlRadioElement->GetChecked(&checked); - /* ----- Need to add this code soon - - nsCOMPtr xulRadioElement(do_QueryInteface(mDOMNode)); - if (xulRadioElement) - xulRadioElement->GetChecked(&checked); - */ - if (checked) *_retval |= STATE_CHECKED; @@ -295,28 +158,25 @@ NS_IMETHODIMP nsHTMLRadioButtonAccessible::GetAccState(PRUint32 *_retval) // ----- Button ----- nsHTMLButtonAccessible::nsHTMLButtonAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell): -nsHTMLFormControlAccessible(aNode, aShell) +nsFormControlAccessible(aNode, aShell) { } -/* PRUint8 getAccNumActions (); */ NS_IMETHODIMP nsHTMLButtonAccessible::GetAccNumActions(PRUint8 *_retval) { - *_retval = 1; + *_retval = eSingle_Action; return NS_OK;; } -/* wstring getAccActionName (in PRUint8 index); */ NS_IMETHODIMP nsHTMLButtonAccessible::GetAccActionName(PRUint8 index, nsAWritableString& _retval) { - if (index == 0) { + if (index == eAction_Click) { _retval = NS_LITERAL_STRING("press"); return NS_OK; } return NS_ERROR_INVALID_ARG; } -/* void accDoAction (in PRUint8 index); */ NS_IMETHODIMP nsHTMLButtonAccessible::AccDoAction(PRUint8 index) { if (index == 0) { @@ -327,14 +187,12 @@ NS_IMETHODIMP nsHTMLButtonAccessible::AccDoAction(PRUint8 index) return NS_ERROR_INVALID_ARG; } -/* unsigned long getAccRole (); */ NS_IMETHODIMP nsHTMLButtonAccessible::GetAccRole(PRUint32 *_retval) { *_retval = ROLE_PUSHBUTTON; return NS_OK; } -/* wstring getAccName (); */ NS_IMETHODIMP nsHTMLButtonAccessible::GetAccName(nsAWritableString& _retval) { nsCOMPtr button(do_QueryInterface(mDOMNode)); @@ -358,24 +216,21 @@ nsBlockAccessible(aNode, aShell) { } -/* PRUint8 getAccNumActions (); */ NS_IMETHODIMP nsHTML4ButtonAccessible::GetAccNumActions(PRUint8 *_retval) { - *_retval = 1; + *_retval = eSingle_Action; return NS_OK;; } -/* wstring getAccActionName (in PRUint8 index); */ NS_IMETHODIMP nsHTML4ButtonAccessible::GetAccActionName(PRUint8 index, nsAWritableString& _retval) { - if (index == 0) { + if (index == eAction_Click) { _retval = NS_LITERAL_STRING("press"); return NS_OK; } return NS_ERROR_INVALID_ARG; } -/* void accDoAction (in PRUint8 index); */ NS_IMETHODIMP nsHTML4ButtonAccessible::AccDoAction(PRUint8 index) { if (index == 0) { @@ -390,14 +245,12 @@ NS_IMETHODIMP nsHTML4ButtonAccessible::AccDoAction(PRUint8 index) return NS_ERROR_INVALID_ARG; } -/* unsigned long getAccRole (); */ NS_IMETHODIMP nsHTML4ButtonAccessible::GetAccRole(PRUint32 *_retval) { *_retval = ROLE_PUSHBUTTON; return NS_OK; } -/* long getAccState (); */ NS_IMETHODIMP nsHTML4ButtonAccessible::GetAccState(PRUint32 *_retval) { nsAccessible::GetAccState(_retval); @@ -405,8 +258,6 @@ NS_IMETHODIMP nsHTML4ButtonAccessible::GetAccState(PRUint32 *_retval) return NS_OK; } - -/* wstring getAccName (); */ NS_IMETHODIMP nsHTML4ButtonAccessible::GetAccName(nsAWritableString& _retval) { nsresult rv = NS_ERROR_FAILURE; @@ -429,18 +280,16 @@ NS_IMETHODIMP nsHTML4ButtonAccessible::GetAccName(nsAWritableString& _retval) // --- textfield ----- nsHTMLTextFieldAccessible::nsHTMLTextFieldAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell): -nsHTMLFormControlAccessible(aNode, aShell) +nsFormControlAccessible(aNode, aShell) { } -/* unsigned long getAccRole (); */ NS_IMETHODIMP nsHTMLTextFieldAccessible::GetAccRole(PRUint32 *_retval) { *_retval = ROLE_TEXT; return NS_OK; } -/* wstring getAccValue (); */ NS_IMETHODIMP nsHTMLTextFieldAccessible::GetAccValue(nsAWritableString& _retval) { PRUint32 state; @@ -463,7 +312,6 @@ NS_IMETHODIMP nsHTMLTextFieldAccessible::GetAccValue(nsAWritableString& _retval) return NS_ERROR_FAILURE; } -/* long getAccState (); */ NS_IMETHODIMP nsHTMLTextFieldAccessible::GetAccState(PRUint32 *_retval) { // can be @@ -511,7 +359,7 @@ NS_IMETHODIMP nsHTMLTextFieldAccessible::GetAccState(PRUint32 *_retval) if (inputElement) { /////// ====== Must be a password field, so it uses nsIDOMHTMLFormControl ==== /////// PRUint32 moreStates = 0; - nsresult rv = nsHTMLFormControlAccessible::GetAccState(&moreStates); + nsresult rv = nsFormControlAccessible::GetAccState(&moreStates); *_retval |= moreStates; return rv; } diff --git a/mozilla/accessible/src/nsHTMLFormControlAccessible.h b/mozilla/accessible/src/nsHTMLFormControlAccessible.h index 13ab8ceb00a..59fa72afcf2 100644 --- a/mozilla/accessible/src/nsHTMLFormControlAccessible.h +++ b/mozilla/accessible/src/nsHTMLFormControlAccessible.h @@ -40,29 +40,12 @@ #ifndef _nsHTMLFormControlAccessible_H_ #define _nsHTMLFormControlAccessible_H_ -#include "nsAccessible.h" #include "nsBaseWidgetAccessible.h" +#include "nsFormControlAccessible.h" class nsICheckboxControlFrame; -/* Accessible for supporting for controls - * supports: - * - walking up to get name from label - * - support basic state - */ -class nsHTMLFormControlAccessible : public nsLeafAccessible -{ - -public: - nsHTMLFormControlAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell); - NS_IMETHOD GetAccName(nsAWritableString& _retval); - NS_IMETHOD GetAccState(PRUint32 *_retval); - -protected: - NS_IMETHODIMP AppendLabelFor(nsIContent *aLookNode, nsAReadableString *aId, nsAWritableString *aLabel); -}; - -class nsHTMLCheckboxAccessible : public nsHTMLFormControlAccessible +class nsHTMLCheckboxAccessible : public nsFormControlAccessible { public: @@ -74,19 +57,16 @@ public: NS_IMETHOD GetAccState(PRUint32 *_retval); }; -class nsHTMLRadioButtonAccessible : public nsHTMLFormControlAccessible +class nsHTMLRadioButtonAccessible : public nsRadioButtonAccessible { public: nsHTMLRadioButtonAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell); - NS_IMETHOD GetAccRole(PRUint32 *_retval); - NS_IMETHOD GetAccNumActions(PRUint8 *_retval); - NS_IMETHOD GetAccActionName(PRUint8 index, nsAWritableString& _retval); NS_IMETHOD AccDoAction(PRUint8 index); NS_IMETHOD GetAccState(PRUint32 *_retval); }; -class nsHTMLButtonAccessible : public nsHTMLFormControlAccessible +class nsHTMLButtonAccessible : public nsFormControlAccessible { public: @@ -111,8 +91,7 @@ public: NS_IMETHOD AccDoAction(PRUint8 index); }; - -class nsHTMLTextFieldAccessible : public nsHTMLFormControlAccessible +class nsHTMLTextFieldAccessible : public nsFormControlAccessible { public: nsHTMLTextFieldAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell); diff --git a/mozilla/accessible/src/nsHTMLListboxAccessible.cpp b/mozilla/accessible/src/nsHTMLListboxAccessible.cpp deleted file mode 100644 index d6a6e46521c..00000000000 --- a/mozilla/accessible/src/nsHTMLListboxAccessible.cpp +++ /dev/null @@ -1,198 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: NPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Netscape 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/NPL/ - * - * 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): - * Original Author: Eric Vaughan (evaughan@netscape.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 - * 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 NPL, 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 NPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#include "nsHTMLListboxAccessible.h" - -#include "nsCOMPtr.h" -#include "nsIAccessibilityService.h" -#include "nsIDOMHTMLCollection.h" -#include "nsIDOMHTMLInputElement.h" -#include "nsIDOMHTMLSelectElement.h" -#include "nsIDOMHTMLOptionElement.h" -#include "nsIFrame.h" -#include "nsIServiceManager.h" -#include "nsLayoutAtoms.h" - -/** ----- nsHTMLListboxAccessible ----- */ - -/** - * Constructor -- create the nsHTMLAccessible - */ -nsHTMLListboxAccessible::nsHTMLListboxAccessible(nsIDOMNode* aDOMNode, - nsIWeakReference* aShell) - :nsAccessible(aDOMNode, aShell) -{ -} - -/** Inherit the ISupports impl from nsAccessible */ -NS_IMPL_ISUPPORTS_INHERITED1(nsHTMLListboxAccessible, nsAccessible, nsIAccessibleSelectable) - -/** - * Tell our caller we are a list ( there isn't a listbox value ) - */ -NS_IMETHODIMP nsHTMLListboxAccessible::GetAccRole(PRUint32 *_retval) -{ - *_retval = ROLE_WINDOW; - return NS_OK; -} - -/** - * Through the arg, pass back our last child, a nsHTMLListboxWindowAccessible object - */ -NS_IMETHODIMP nsHTMLListboxAccessible::GetAccLastChild(nsIAccessible **_retval) -{ - *_retval = new nsHTMLSelectListAccessible(this, mDOMNode, mPresShell); - if ( ! *_retval ) - return NS_ERROR_FAILURE; - NS_ADDREF(*_retval); - return NS_OK; -} - -/** - * Through the arg, pass back our first child, a nsHTMLListboxWindowAccessible object - */ -NS_IMETHODIMP nsHTMLListboxAccessible::GetAccFirstChild(nsIAccessible **_retval) -{ - *_retval = new nsHTMLSelectListAccessible(this, mDOMNode, mPresShell); - if ( ! *_retval ) - return NS_ERROR_FAILURE; - NS_ADDREF(*_retval); - return NS_OK; -} - -/** - * We always have 1 child: SelectList. - */ -NS_IMETHODIMP nsHTMLListboxAccessible::GetAccChildCount(PRInt32 *_retval) -{ - *_retval = 1; - return NS_OK; -} - -/** - * nsIAccessibleSelectable method. This needs to get from the select the list - * of select options and then iterate through that pulling out the selected - * items and creating IAccessible objects for them. Put the IAccessibles in - * the nsISupportsArray and return them. - * retval will be nsnull if: - * - there are no options in the select - * - 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; -} - -/** - * Our value is the value of our ( first ) selected child. SelectElement - * returns this by default with GetValue(). - */ -NS_IMETHODIMP nsHTMLListboxAccessible::GetAccValue(nsAWritableString& _retval) -{ - nsCOMPtr select (do_QueryInterface(mDOMNode)); - if ( select ) { - select->GetValue(_retval); - return NS_OK; - } - return NS_ERROR_FAILURE; -} - -/** - * As a nsHTMLListboxAccessible we can have the following states: - * STATE_FOCUSED - * STATE_READONLY - * STATE_FOCUSABLE - */ -NS_IMETHODIMP nsHTMLListboxAccessible::GetAccState(PRUint32 *_retval) -{ - // this sets either STATE_FOCUSED or 0 - nsAccessible::GetAccState(_retval); - - *_retval |= STATE_READONLY | STATE_FOCUSABLE; - - return NS_OK; -} - - - diff --git a/mozilla/accessible/src/nsHTMLSelectAccessible.cpp b/mozilla/accessible/src/nsHTMLSelectAccessible.cpp index 3821122d361..0be4b1a43c8 100644 --- a/mozilla/accessible/src/nsHTMLSelectAccessible.cpp +++ b/mozilla/accessible/src/nsHTMLSelectAccessible.cpp @@ -37,680 +37,77 @@ * * ***** END LICENSE BLOCK ***** */ -#include "nsHTMLSelectAccessible.h" #include "nsCOMPtr.h" -#include "nsIDocument.h" -#include "nsIPresShell.h" -#include "nsIPresContext.h" -#include "nsIContent.h" -#include "nsIFrame.h" -#include "nsRootAccessible.h" -#include "nsINameSpaceManager.h" -#include "nsIDOMHTMLInputElement.h" -#include "nsLayoutAtoms.h" -#include "nsIDOMXULListener.h" -#include "nsIDOMEventReceiver.h" -#include "nsReadableUtils.h" -#include "nsIDOMHTMLCollection.h" -#include "nsISelectElement.h" -#include "nsIDOMHTMLSelectElement.h" +#include "nsHTMLSelectAccessible.h" #include "nsIAccessibilityService.h" -#include "nsIServiceManager.h" +#include "nsIFrame.h" +#include "nsIComboboxControlFrame.h" +#include "nsIDOMEventReceiver.h" +#include "nsIDOMHTMLCollection.h" +#include "nsIDOMHTMLInputElement.h" #include "nsIDOMHTMLOptionElement.h" - -/* - * A class the represents the text field in the Select to the left - * of the drop down button - */ -class nsHTMLSelectTextFieldAccessible : public nsLeafAccessible -{ -public: - - nsHTMLSelectTextFieldAccessible(nsIAccessible* aParent, nsIDOMNode* aDOMNode, nsIWeakReference* aShell); - - NS_IMETHOD GetAccNextSibling(nsIAccessible **_retval); - NS_IMETHOD GetAccPreviousSibling(nsIAccessible **_retval); - NS_IMETHOD GetAccParent(nsIAccessible **_retval); - NS_IMETHOD GetAccRole(PRUint32 *_retval); - NS_IMETHOD GetAccValue(nsAWritableString& _retval); - - virtual void GetBounds(nsRect& aBounds, nsIFrame** aRelativeFrame); - - nsCOMPtr mParent; -}; - -/* - * A base class that can listen to menu events. Its used so the - * button and the window accessibles can change there name and role - * depending on whether the drop down list is dropped down on not - */ -class nsMenuListenerAccessible : public nsAccessible, public nsIDOMXULListener -{ -public: - - NS_DECL_ISUPPORTS_INHERITED - - nsMenuListenerAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell); - virtual ~nsMenuListenerAccessible(); - - // popup listener - 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(); - - PRBool mRegistered; - PRBool mOpen; -}; - -NS_IMPL_ISUPPORTS_INHERITED1(nsMenuListenerAccessible, nsAccessible, nsIDOMXULListener) +#include "nsIDOMHTMLSelectElement.h" +#include "nsIListControlFrame.h" +#include "nsIServiceManager.h" +#include "nsLayoutAtoms.h" /** - * A class that represents the button inside the Select to the right of the text field - */ -class nsHTMLSelectButtonAccessible : public nsMenuListenerAccessible -{ -public: - - nsHTMLSelectButtonAccessible(nsIAccessible* aParent, nsIDOMNode* aDOMNode, nsIWeakReference* aShell); + * Selects, Listboxes and Comboboxes, are made up of a number of different + * widgets, some of which are shared between the two. This file contains + * all of the widgets for both of the Selects, for HTML only. Some of them + * extend classes from nsSelectAccessible.cpp, which contains base classes + * that are also extended by the XUL Select Accessibility support. + * + * Listbox: + * - nsHTMLListboxAccessible + * - nsHTMLSelctListAccessible + * - nsHTMLSelectOptionAccessible + * + * Comboboxes: + * - nsHTMLComboboxAccessilbe + * - nsHTMLComboboxTextFieldAccessible + * - nsHTMLComboboxButtonAccessible + * - nsHTMLComboboxWindowAccessilbe + * - nsHTMLSelctListAccessible + * - nsHTMLSelectOptionAccessible + */ - NS_IMETHOD GetAccNextSibling(nsIAccessible **_retval); - NS_IMETHOD GetAccPreviousSibling(nsIAccessible **_retval); - NS_IMETHOD GetAccParent(nsIAccessible **_retval); - NS_IMETHOD GetAccName(nsAWritableString& _retval); - NS_IMETHOD GetAccRole(PRUint32 *_retval); - NS_IMETHOD GetAccLastChild(nsIAccessible **_retval); - NS_IMETHOD GetAccFirstChild(nsIAccessible **_retval); - NS_IMETHOD GetAccChildCount(PRInt32 *_retval); - NS_IMETHOD GetAccNumActions(PRUint8 *_retval); - NS_IMETHOD GetAccActionName(PRUint8 index, nsAWritableString& _retval); - NS_IMETHOD AccDoAction(PRUint8 index); +/** ------------------------------------------------------ */ +/** First, the common widgets */ +/** ------------------------------------------------------ */ +/** ----- nsHTMLSelectListAccessible ----- */ - virtual void GetBounds(nsRect& aBounds, nsIFrame** aRelativeFrame); - - - - nsCOMPtr mParent; -}; - -/* - * A class that represents the window that lives to the right - * of the drop down button inside the Select. This is the window - * that is made visible when the button is pressed. - */ -class nsHTMLSelectWindowAccessible : public nsMenuListenerAccessible -{ -public: - - nsHTMLSelectWindowAccessible(nsIAccessible* aParent, nsIDOMNode* aDOMNode, nsIWeakReference* aShell); - - NS_IMETHOD GetAccParent(nsIAccessible **_retval); - NS_IMETHOD GetAccNextSibling(nsIAccessible **_retval); - NS_IMETHOD GetAccPreviousSibling(nsIAccessible **_retval); - NS_IMETHOD GetAccLastChild(nsIAccessible **_retval); - NS_IMETHOD GetAccFirstChild(nsIAccessible **_retval); - NS_IMETHOD GetAccChildCount(PRInt32 *_retval); - NS_IMETHOD GetAccRole(PRUint32 *_retval); - NS_IMETHOD GetAccState(PRUint32 *_retval); - - virtual void GetBounds(nsRect& aBounds, nsIFrame** aRelativeFrame); - - nsCOMPtr mParent; -}; - -/* - * The list that contains all the options in the select. It is inside the window. - */ -class nsHTMLSelectListAccessible : public nsAccessible -{ -public: - - nsHTMLSelectListAccessible(nsIAccessible* aParent, nsIDOMNode* aDOMNode, nsIWeakReference* aShell); - virtual ~nsHTMLSelectListAccessible() {} - - NS_IMETHOD GetAccParent(nsIAccessible **_retval); - NS_IMETHOD GetAccRole(PRUint32 *_retval); - NS_IMETHOD GetAccNextSibling(nsIAccessible **_retval); - NS_IMETHOD GetAccPreviousSibling(nsIAccessible **_retval); - NS_IMETHOD AccGetBounds(PRInt32 *x, PRInt32 *y, PRInt32 *width, PRInt32 *height); - NS_IMETHOD GetAccLastChild(nsIAccessible **_retval); - NS_IMETHOD GetAccFirstChild(nsIAccessible **_retval); - - nsCOMPtr mParent; -}; - -//--------- nsHTMLSelectAccessible ----- - -nsHTMLSelectAccessible::nsHTMLSelectAccessible(nsIDOMNode* aDOMNode, - nsIWeakReference* aShell) - :nsAccessible(aDOMNode, aShell) +/** Default Constructor */ +nsHTMLSelectListAccessible::nsHTMLSelectListAccessible(nsIAccessible* aParent, + nsIDOMNode* aDOMNode, + nsIWeakReference* aShell) +:nsSelectListAccessible(aParent, aDOMNode, aShell) { } -NS_IMPL_ISUPPORTS_INHERITED1(nsHTMLSelectAccessible, nsAccessible, nsIAccessibleSelectable) - -// ------------- Helper method for determination of proper Frame ------ -//static -PRBool nsHTMLSelectAccessible::IsCorrectFrame( nsIFrame* aFrame, nsIAtom* aAtom ) { - if (!aFrame || !aAtom) - return PR_FALSE; - nsCOMPtr frameType; - aFrame->GetFrameType(getter_AddRefs(frameType)); - if (frameType.get() != aAtom) - return PR_FALSE; - return PR_TRUE; -} - -NS_IMETHODIMP nsHTMLSelectAccessible::GetAccValue(nsAWritableString& _retval) +/** + * As a nsHTMLSelectListAccessible we can have the following states: + * STATE_MULTISELECTABLE + * STATE_EXTSELECTABLE + */ +NS_IMETHODIMP nsHTMLSelectListAccessible::GetAccState(PRUint32 *_retval) { - nsCOMPtr text; - GetAccFirstChild(getter_AddRefs(text)); - if (text) - return text->GetAccValue(_retval); - - return NS_ERROR_FAILURE; -} - - -NS_IMETHODIMP nsHTMLSelectAccessible::GetAccRole(PRUint32 *_retval) -{ - *_retval = ROLE_COMBOBOX; - return NS_OK; -} - -NS_IMETHODIMP nsHTMLSelectAccessible::GetAccLastChild(nsIAccessible **_retval) -{ - // create a window accessible - *_retval = new nsHTMLSelectWindowAccessible(this, mDOMNode, mPresShell); - if ( ! *_retval ) - return NS_ERROR_FAILURE; - NS_ADDREF(*_retval); - return NS_OK; -} - -NS_IMETHODIMP nsHTMLSelectAccessible::GetAccFirstChild(nsIAccessible **_retval) -{ - // create a text field - - *_retval = new nsHTMLSelectTextFieldAccessible(this, mDOMNode, mPresShell); - if ( ! *_retval ) - return NS_ERROR_FAILURE; - NS_ADDREF(*_retval); - return NS_OK; -} - -NS_IMETHODIMP nsHTMLSelectAccessible::GetAccChildCount(PRInt32 *_retval) -{ - // always have 3 children - *_retval = 3; - return NS_OK; -} - -NS_IMETHODIMP nsHTMLSelectAccessible::GetSelectedChildren(nsISupportsArray **_retval) -{ - *_retval = nsnull; - return NS_OK; -} - -//-------- SelectTextFieldAccessible ------ - -nsHTMLSelectTextFieldAccessible::nsHTMLSelectTextFieldAccessible(nsIAccessible* aParent, nsIDOMNode* aDOMNode, nsIWeakReference* aShell): -nsLeafAccessible(aDOMNode, aShell) -{ - mParent = aParent; -} - -NS_IMETHODIMP nsHTMLSelectTextFieldAccessible::GetAccValue(nsAWritableString& _retval) -{ - nsIFrame* frame = nsAccessible::GetBoundsFrame(); - nsCOMPtr context; - GetPresContext(context); - if ( !frame ) - return NS_ERROR_FAILURE; - - frame->FirstChild(context, nsnull, &frame); - if ( ! nsHTMLSelectAccessible::IsCorrectFrame( frame, nsLayoutAtoms::blockFrame) ) - return NS_ERROR_FAILURE; - - frame->FirstChild(context, nsnull, &frame); - if ( ! nsHTMLSelectAccessible::IsCorrectFrame( frame, nsLayoutAtoms::textFrame) ) - return NS_ERROR_FAILURE; - - nsCOMPtr content; - frame->GetContent(getter_AddRefs(content)); - - if (!content) - return NS_ERROR_FAILURE; - - AppendFlatStringFromSubtree(content, &_retval); - - return NS_OK; -} - -void nsHTMLSelectTextFieldAccessible::GetBounds(nsRect& aBounds, nsIFrame** aRelativeFrame) -{ - // get our first child's frame - nsIFrame* frame = nsAccessible::GetBoundsFrame(); - nsCOMPtr context; - GetPresContext(context); - if ( !frame ) - return; - - frame->FirstChild(context, nsnull, &frame); - if ( ! nsHTMLSelectAccessible::IsCorrectFrame( frame, nsLayoutAtoms::blockFrame) ) - return; - - frame->GetParent(aRelativeFrame); - if ( ! nsHTMLSelectAccessible::IsCorrectFrame( *aRelativeFrame, nsLayoutAtoms::areaFrame) ) - return; - - frame->GetRect(aBounds); -} - -NS_IMETHODIMP nsHTMLSelectTextFieldAccessible::GetAccParent(nsIAccessible **_retval) -{ - *_retval = mParent; - NS_IF_ADDREF(*_retval); - return NS_OK; -} - -NS_IMETHODIMP nsHTMLSelectTextFieldAccessible::GetAccNextSibling(nsIAccessible **_retval) -{ - nsCOMPtr parent; - GetAccParent(getter_AddRefs(parent)); - - *_retval = new nsHTMLSelectButtonAccessible(parent, mDOMNode, mPresShell); - if ( ! *_retval ) - return NS_ERROR_FAILURE; - NS_ADDREF(*_retval); - return NS_OK; -} - -NS_IMETHODIMP nsHTMLSelectTextFieldAccessible::GetAccPreviousSibling(nsIAccessible **_retval) -{ - *_retval = nsnull; - return NS_OK; -} - -NS_IMETHODIMP nsHTMLSelectTextFieldAccessible::GetAccRole(PRUint32 *_retval) -{ - *_retval = ROLE_STATICTEXT; - return NS_OK; -} - -// --------- nsMenuListenerAccessible ----------- - -nsMenuListenerAccessible::nsMenuListenerAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell): -nsAccessible(aDOMNode, aShell) -{ - mRegistered = PR_FALSE; - mOpen = PR_FALSE; -} - -nsMenuListenerAccessible::~nsMenuListenerAccessible() -{ - if (mRegistered) { - nsCOMPtr eventReceiver(do_QueryInterface(mDOMNode)); - if (eventReceiver) - eventReceiver->RemoveEventListener(NS_LITERAL_STRING("popupshowing"), this, PR_TRUE); - } -} - -NS_IMETHODIMP nsMenuListenerAccessible::PopupShowing(nsIDOMEvent* aEvent) -{ - mOpen = PR_TRUE; - - /* TBD send state change event */ - - return NS_OK; -} - -NS_IMETHODIMP nsMenuListenerAccessible::PopupHiding(nsIDOMEvent* aEvent) -{ - mOpen = PR_FALSE; - - /* TBD send state change event */ - - return NS_OK; -} - -NS_IMETHODIMP nsMenuListenerAccessible::Close(nsIDOMEvent* aEvent) -{ - mOpen = PR_FALSE; - - /* TBD send state change event */ - - return NS_OK; -} - -void -nsMenuListenerAccessible::SetupMenuListener() -{ - // not not already one register ourselves as a popup listener - if (!mRegistered) { - - nsCOMPtr eventReceiver(do_QueryInterface(mDOMNode)); - if (!eventReceiver) { - return; - } - - nsresult rv = eventReceiver->AddEventListener(NS_LITERAL_STRING("popupshowing"), this, PR_TRUE); - - if (NS_FAILED(rv)) { - return; - } - - mRegistered = PR_TRUE; + nsCOMPtr select (do_QueryInterface(mDOMNode)); + if ( select ) { + PRBool multiple; + select->GetMultiple(&multiple); + if ( multiple ) + *_retval |= STATE_MULTISELECTABLE | STATE_EXTSELECTABLE; } -} - - -//-------- SelectButtonAccessible ------ - -nsHTMLSelectButtonAccessible::nsHTMLSelectButtonAccessible(nsIAccessible* aParent, nsIDOMNode* aDOMNode, nsIWeakReference* aShell): -nsMenuListenerAccessible(aDOMNode, aShell) -{ - mParent = aParent; -} - -/* void accDoAction (in PRUint8 index); */ -NS_IMETHODIMP nsHTMLSelectButtonAccessible::AccDoAction(PRUint8 index) -{ - nsIFrame* frame = nsAccessible::GetBoundsFrame(); - nsCOMPtr context; - GetPresContext(context); - - frame->FirstChild(context, nsnull, &frame); - if ( ! nsHTMLSelectAccessible::IsCorrectFrame( frame, nsLayoutAtoms::blockFrame) ) - return NS_ERROR_FAILURE; - - frame->GetNextSibling(&frame); - if ( ! nsHTMLSelectAccessible::IsCorrectFrame( frame, nsLayoutAtoms::gfxButtonControlFrame) ) - return NS_ERROR_FAILURE; - - nsCOMPtr content; - frame->GetContent(getter_AddRefs(content)); - - if (index == 0) { - nsCOMPtr element(do_QueryInterface(content)); - if (element) - { - element->Click(); - return NS_OK; - } - return NS_ERROR_FAILURE; - } - return NS_ERROR_NOT_IMPLEMENTED; -} - -/* PRUint8 getAccNumActions (); */ -NS_IMETHODIMP nsHTMLSelectButtonAccessible::GetAccNumActions(PRUint8 *_retval) -{ - *_retval = 1; - return NS_OK; -} - -void nsHTMLSelectButtonAccessible::GetBounds(nsRect& aBounds, nsIFrame** aRelativeFrame) -{ - // get our second child's frame - nsIFrame* frame = nsAccessible::GetBoundsFrame(); - nsCOMPtr context; - GetPresContext(context); - - frame->FirstChild(context, nsnull, &frame); - if ( ! nsHTMLSelectAccessible::IsCorrectFrame( frame, nsLayoutAtoms::blockFrame) ) - return; - - frame->GetNextSibling(&frame); - if ( ! nsHTMLSelectAccessible::IsCorrectFrame( frame, nsLayoutAtoms::gfxButtonControlFrame) ) - return; - - frame->GetParent(aRelativeFrame); - if ( ! nsHTMLSelectAccessible::IsCorrectFrame( *aRelativeFrame, nsLayoutAtoms::areaFrame) ) - return; - - frame->GetRect(aBounds); -} - -NS_IMETHODIMP nsHTMLSelectButtonAccessible::GetAccRole(PRUint32 *_retval) -{ - *_retval = ROLE_PUSHBUTTON; - return NS_OK; -} - -NS_IMETHODIMP nsHTMLSelectButtonAccessible::GetAccParent(nsIAccessible **_retval) -{ - *_retval = mParent; - NS_IF_ADDREF(*_retval); - return NS_OK; -} - - -NS_IMETHODIMP nsHTMLSelectButtonAccessible::GetAccName(nsAWritableString& _retval) -{ - return GetAccActionName(0, _retval); -} - -NS_IMETHODIMP nsHTMLSelectButtonAccessible::GetAccActionName(PRUint8 index, nsAWritableString& _retval) -{ - SetupMenuListener(); - - // get the current state open or closed - // set _retval to it. - // notice its supposed to be reversed. Close if opened - // and Open if closed. - - if (mOpen) - _retval = NS_LITERAL_STRING("Close"); - else - _retval = NS_LITERAL_STRING("Open"); - - return NS_OK; -} - - -NS_IMETHODIMP nsHTMLSelectButtonAccessible::GetAccNextSibling(nsIAccessible **_retval) -{ - nsCOMPtr parent; - GetAccParent(getter_AddRefs(parent)); - - *_retval = new nsHTMLSelectWindowAccessible(parent, mDOMNode, mPresShell); - if ( ! *_retval ) - return NS_ERROR_FAILURE; - NS_ADDREF(*_retval); - return NS_OK; -} - -NS_IMETHODIMP nsHTMLSelectButtonAccessible::GetAccPreviousSibling(nsIAccessible **_retval) -{ - nsCOMPtr parent; - GetAccParent(getter_AddRefs(parent)); - - *_retval = new nsHTMLSelectTextFieldAccessible(parent, mDOMNode, mPresShell); - if ( ! *_retval ) - return NS_ERROR_FAILURE; - NS_ADDREF(*_retval); - return NS_OK; -} - -NS_IMETHODIMP nsHTMLSelectButtonAccessible::GetAccLastChild(nsIAccessible **_retval) -{ - *_retval = nsnull; - return NS_OK; -} - -NS_IMETHODIMP nsHTMLSelectButtonAccessible::GetAccFirstChild(nsIAccessible **_retval) -{ - *_retval = nsnull; - return NS_OK; -} - -NS_IMETHODIMP nsHTMLSelectButtonAccessible::GetAccChildCount(PRInt32 *_retval) -{ - *_retval = 0; - return NS_OK; -} - -//--------------------- - - -nsHTMLSelectWindowAccessible::nsHTMLSelectWindowAccessible(nsIAccessible* aParent, nsIDOMNode* aDOMNode, nsIWeakReference* aShell) -:nsMenuListenerAccessible(aDOMNode, aShell) -{ - mParent = aParent; -} - - -NS_IMETHODIMP nsHTMLSelectWindowAccessible::GetAccState(PRUint32 *_retval) -{ - nsAccessible::GetAccState(_retval); - - SetupMenuListener(); - - // if open we are visible if closed we are invisible - // set _retval to it. - if (mOpen) - *_retval |= STATE_DEFAULT; - else - *_retval |= STATE_INVISIBLE; - - return NS_OK; -} - -NS_IMETHODIMP nsHTMLSelectWindowAccessible::GetAccRole(PRUint32 *_retval) -{ - *_retval = ROLE_WINDOW; - return NS_OK; -} - -NS_IMETHODIMP nsHTMLSelectWindowAccessible::GetAccParent(nsIAccessible **_retval) -{ - *_retval = mParent; - NS_IF_ADDREF(*_retval); - return NS_OK; -} - -NS_IMETHODIMP nsHTMLSelectWindowAccessible::GetAccPreviousSibling(nsIAccessible **_retval) -{ - nsCOMPtr parent; - GetAccParent(getter_AddRefs(parent)); - - *_retval = new nsHTMLSelectButtonAccessible(parent, mDOMNode, mPresShell); - if ( ! *_retval ) - return NS_ERROR_FAILURE; - NS_ADDREF(*_retval); - return NS_OK; -} - -NS_IMETHODIMP nsHTMLSelectWindowAccessible::GetAccNextSibling(nsIAccessible **_retval) -{ - *_retval = nsnull; - return NS_OK; -} - -NS_IMETHODIMP nsHTMLSelectWindowAccessible::GetAccLastChild(nsIAccessible **_retval) -{ - *_retval = new nsHTMLSelectListAccessible(this, mDOMNode, mPresShell); - if ( ! *_retval ) - return NS_ERROR_FAILURE; - NS_ADDREF(*_retval); - return NS_OK; -} - -NS_IMETHODIMP nsHTMLSelectWindowAccessible::GetAccFirstChild(nsIAccessible **_retval) -{ - *_retval = new nsHTMLSelectListAccessible(this, mDOMNode, mPresShell); - if ( ! *_retval ) - return NS_ERROR_FAILURE; - NS_ADDREF(*_retval); - return NS_OK; -} - -NS_IMETHODIMP nsHTMLSelectWindowAccessible::GetAccChildCount(PRInt32 *_retval) -{ - *_retval = 1; - return NS_OK; -} - -void nsHTMLSelectWindowAccessible::GetBounds(nsRect& aBounds, nsIFrame** aRelativeFrame) -{ - // get our first option - nsCOMPtr child; - mDOMNode->GetFirstChild(getter_AddRefs(child)); - - // now get its frame - nsCOMPtr shell(do_QueryReferent(mPresShell)); - if (!shell) { - *aRelativeFrame = nsnull; - return; - } - - nsIFrame* frame = nsnull; - nsCOMPtr content(do_QueryInterface(child)); - shell->GetPrimaryFrameFor(content, &frame); - if ( ! nsHTMLSelectAccessible::IsCorrectFrame( frame, nsLayoutAtoms::blockFrame) ) - return; - - frame->GetParent(&frame); - if ( ! nsHTMLSelectAccessible::IsCorrectFrame( frame, nsLayoutAtoms::areaFrame) ) - return; - - frame->GetParent(aRelativeFrame); - if ( ! nsHTMLSelectAccessible::IsCorrectFrame( *aRelativeFrame, nsLayoutAtoms::listControlFrame) ) - return; - - frame->GetRect(aBounds); -} - -//---------- - - -nsHTMLSelectListAccessible::nsHTMLSelectListAccessible(nsIAccessible* aParent, nsIDOMNode* aDOMNode, nsIWeakReference* aShell) -:nsAccessible(aDOMNode, aShell) -{ - mParent = aParent; -} - -NS_IMETHODIMP nsHTMLSelectListAccessible::AccGetBounds(PRInt32 *x, PRInt32 *y, PRInt32 *width, PRInt32 *height) -{ - return mParent->AccGetBounds(x,y,width,height); -} - -NS_IMETHODIMP nsHTMLSelectListAccessible::GetAccParent(nsIAccessible **_retval) -{ - *_retval = mParent; - NS_ADDREF(*_retval); - return NS_OK; -} - -NS_IMETHODIMP nsHTMLSelectListAccessible::GetAccRole(PRUint32 *_retval) -{ - *_retval = ROLE_LIST; - return NS_OK; -} - -NS_IMETHODIMP nsHTMLSelectListAccessible::GetAccPreviousSibling(nsIAccessible **_retval) -{ - *_retval = nsnull; - return NS_OK; -} - -NS_IMETHODIMP nsHTMLSelectListAccessible::GetAccNextSibling(nsIAccessible **_retval) -{ - *_retval = nsnull; return NS_OK; } +/** + * Gets the last child of the DOM node and creates and returns + * a nsHTMLSelectOptionAccessible. + */ NS_IMETHODIMP nsHTMLSelectListAccessible::GetAccLastChild(nsIAccessible **_retval) { nsCOMPtr last; @@ -723,6 +120,10 @@ NS_IMETHODIMP nsHTMLSelectListAccessible::GetAccLastChild(nsIAccessible **_retva return NS_OK; } +/** + * Gets the First child of the DOM node and creates and returns + * a nsHTMLSelectOptionAccessible. + */ NS_IMETHODIMP nsHTMLSelectListAccessible::GetAccFirstChild(nsIAccessible **_retval) { nsCOMPtr first; @@ -735,27 +136,18 @@ NS_IMETHODIMP nsHTMLSelectListAccessible::GetAccFirstChild(nsIAccessible **_retv return NS_OK; } -//-------- +/** ----- nsHTMLSelectOptionAccessible ----- */ +/** Default Constructor */ nsHTMLSelectOptionAccessible::nsHTMLSelectOptionAccessible(nsIAccessible* aParent, nsIDOMNode* aDOMNode, nsIWeakReference* aShell): -nsLeafAccessible(aDOMNode, aShell) +nsSelectOptionAccessible(aParent, aDOMNode, aShell) { - mParent = aParent; -} - -NS_IMETHODIMP nsHTMLSelectOptionAccessible::GetAccRole(PRUint32 *_retval) -{ - *_retval = ROLE_LISTITEM; - return NS_OK; -} - -NS_IMETHODIMP nsHTMLSelectOptionAccessible::GetAccParent(nsIAccessible **_retval) -{ - *_retval = mParent; - NS_IF_ADDREF(*_retval); - return NS_OK; } +/** + * Gets the next sibling of the DOM node and creates and returns + * a nsHTMLSelectOptionAccessible. + */ NS_IMETHODIMP nsHTMLSelectOptionAccessible::GetAccNextSibling(nsIAccessible **_retval) { *_retval = nsnull; @@ -773,6 +165,10 @@ NS_IMETHODIMP nsHTMLSelectOptionAccessible::GetAccNextSibling(nsIAccessible **_r return NS_OK; } +/** + * Gets the previous sibling of the DOM node and creates and returns + * a nsHTMLSelectOptionAccessible. + */ NS_IMETHODIMP nsHTMLSelectOptionAccessible::GetAccPreviousSibling(nsIAccessible **_retval) { *_retval = nsnull; @@ -790,20 +186,404 @@ NS_IMETHODIMP nsHTMLSelectOptionAccessible::GetAccPreviousSibling(nsIAccessible return NS_OK; } -NS_IMETHODIMP nsHTMLSelectOptionAccessible::GetAccName(nsAWritableString& _retval) +/** + * As a nsHTMLSelectOptionAccessible we can have the following states: + * STATE_SELECTABLE + * STATE_SELECTED + * STATE_FOCUSED + * STATE_FOCUSABLE + * STATE_INVISIBLE -- not implemented yet + */ +NS_IMETHODIMP nsHTMLSelectOptionAccessible::GetAccState(PRUint32 *_retval) { - nsCOMPtr content (do_QueryInterface(mDOMNode)); - if (!content) { - return NS_ERROR_FAILURE; + *_retval = 0; + nsCOMPtr focusedOptionNode, parentNode; + mParent->AccGetDOMNode(getter_AddRefs(parentNode)); + // find out if we are the focused node + GetFocusedOptionNode(mPresShell, parentNode, focusedOptionNode); + if (focusedOptionNode == mDOMNode) + *_retval |= STATE_FOCUSED; + + // Are we selected? + nsCOMPtr option (do_QueryInterface(mDOMNode)); + if ( option ) { + PRBool isSelected = PR_FALSE; + option->GetSelected(&isSelected); + if ( isSelected ) + *_retval |= STATE_SELECTED; } - nsAutoString option; - nsresult rv = AppendFlatStringFromSubtree(content, &option); + *_retval |= STATE_SELECTABLE | STATE_FOCUSABLE; + + return NS_OK; +} + +/** + * Helper method for getting the focused DOM Node from our parent(list) node. We + * need to use the frame to get the focused option because for some reason we + * weren't getting the proper notification when the focus changed using the DOM + */ +nsresult nsHTMLSelectOptionAccessible::GetFocusedOptionNode(nsIWeakReference *aPresShell, + nsIDOMNode *aListNode, + nsCOMPtr& aFocusedOptionNode) +{ + NS_ASSERTION(aListNode, "Called GetFocusedOptionNode without a valid list node"); + nsCOMPtr shell(do_QueryReferent(aPresShell)); + if (!shell) + return NS_ERROR_FAILURE; + + nsIFrame *frame = nsnull; + nsCOMPtr content(do_QueryInterface(aListNode)); + shell->GetPrimaryFrameFor(content, &frame); + + nsresult rv; + nsCOMPtr listFrame(do_QueryInterface(frame, &rv)); + if (NS_FAILED(rv)) + return rv; // How can list content not have a list frame? + NS_ASSERTION(listFrame, "We don't have a list frame, but rv returned a success code."); + + // Get what's focused by asking frame for "selected item". + PRInt32 focusedOptionIndex = 0; + rv = listFrame->GetSelectedIndex(&focusedOptionIndex); + + nsCOMPtr options; + + // Get options if (NS_SUCCEEDED(rv)) { - // Temp var needed until CompressWhitespace built for nsAWritableString - option.CompressWhitespace(); - _retval.Assign(option); + nsCOMPtr selectElement(do_QueryInterface(aListNode)); + NS_ASSERTION(selectElement, "No select element where it should be"); + rv = selectElement->GetOptions(getter_AddRefs(options)); } + + // Either use options and focused index, or default to list node itself + if (NS_SUCCEEDED(rv) && options && focusedOptionIndex >= 0) // Something is focused + rv = options->Item(focusedOptionIndex, getter_AddRefs(aFocusedOptionNode)); + else { // If no options in list or focusedOptionIndex <0, then we are not focused on an item + aFocusedOptionNode = aListNode; // return normal target content + rv = NS_OK; + } + return rv; } +/** ------------------------------------------------------ */ +/** Secondly, the Listbox widget */ +/** ------------------------------------------------------ */ + +/** ----- nsHTMLListboxAccessible ----- */ + +/** Constructor */ +nsHTMLListboxAccessible::nsHTMLListboxAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell): +nsListboxAccessible(aDOMNode, aShell) +{ +} + +/** Inherit the ISupports impl from nsAccessible, we handle nsIAccessibleSelectable */ +NS_IMPL_ISUPPORTS_INHERITED1(nsHTMLListboxAccessible, nsListboxAccessible, nsIAccessibleSelectable) + +/** + * Our last (and only) child is an nsHTMLSelectListAccessible object + */ +NS_IMETHODIMP nsHTMLListboxAccessible::GetAccLastChild(nsIAccessible **_retval) +{ + *_retval = new nsHTMLSelectListAccessible(this, mDOMNode, mPresShell); + if ( ! *_retval ) + return NS_ERROR_FAILURE; + NS_ADDREF(*_retval); + return NS_OK; +} + +/** + * Our first (and only) child is an nsHTMLSelectListAccessible object + */ +NS_IMETHODIMP nsHTMLListboxAccessible::GetAccFirstChild(nsIAccessible **_retval) +{ + *_retval = new nsHTMLSelectListAccessible(this, mDOMNode, mPresShell); + if ( ! *_retval ) + return NS_ERROR_FAILURE; + NS_ADDREF(*_retval); + return NS_OK; +} + +/** + * Our value is the value of our ( first ) selected child. nsIDOMHTMLSelectElement + * returns this by default with GetValue(). + */ +NS_IMETHODIMP nsHTMLListboxAccessible::GetAccValue(nsAWritableString& _retval) +{ + nsCOMPtr select (do_QueryInterface(mDOMNode)); + if ( select ) { + select->GetValue(_retval); + return NS_OK; + } + 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) +{ +} + +/** + * Our last child is an nsHTMLComboboxWindowAccessible object + */ +NS_IMETHODIMP nsHTMLComboboxAccessible::GetAccLastChild(nsIAccessible **_retval) +{ + *_retval = new nsHTMLComboboxWindowAccessible(this, mDOMNode, mPresShell); + if (! *_retval) + return NS_ERROR_FAILURE; + NS_ADDREF(*_retval); + return NS_OK; +} + +/** + * Our last child is an nsHTMLComboboxTextFieldAccessible object + */ +NS_IMETHODIMP nsHTMLComboboxAccessible::GetAccFirstChild(nsIAccessible **_retval) +{ + *_retval = new nsHTMLComboboxTextFieldAccessible(this, mDOMNode, mPresShell); + if (! *_retval) + return NS_ERROR_FAILURE; + NS_ADDREF(*_retval); + return NS_OK; +} + +/** + * Our value is the value of our ( first ) selected child. nsIDOMHTMLSelectElement + * returns this by default with GetValue(). + */ +NS_IMETHODIMP nsHTMLComboboxAccessible::GetAccValue(nsAWritableString& _retval) +{ + nsCOMPtr select (do_QueryInterface(mDOMNode)); + if (select) { + select->GetValue(_retval); + return NS_OK; + } + return NS_ERROR_FAILURE; +} + +/** ----- nsHTMLComboboxTextFieldAccessible ----- */ + +/** Constructor */ +nsHTMLComboboxTextFieldAccessible::nsHTMLComboboxTextFieldAccessible(nsIAccessible* aParent, + nsIDOMNode* aDOMNode, + nsIWeakReference* aShell): +nsComboboxTextFieldAccessible(aParent, aDOMNode, aShell) +{ +} + +/** + * Our next sibling is an nsHTMLComboboxButtonAccessible object + */ +NS_IMETHODIMP nsHTMLComboboxTextFieldAccessible::GetAccNextSibling(nsIAccessible **_retval) +{ + nsCOMPtr parent; + GetAccParent(getter_AddRefs(parent)); + + *_retval = new nsHTMLComboboxButtonAccessible(parent, mDOMNode, mPresShell); + if (! *_retval) + return NS_ERROR_FAILURE; + NS_ADDREF(*_retval); + return NS_OK; +} + +/** -----ComboboxButtonAccessible ----- */ + +/** Constructor -- cache our parent */ +nsHTMLComboboxButtonAccessible::nsHTMLComboboxButtonAccessible(nsIAccessible* aParent, + nsIDOMNode* aDOMNode, + nsIWeakReference* aShell): +nsComboboxButtonAccessible(aParent, aDOMNode, aShell) +{ +} + +/** + * Programmaticaly click on the button, causing either the display or + * the hiding of the drop down box ( window ). + * Walks the Frame tree and checks for proper frames. + */ +NS_IMETHODIMP nsHTMLComboboxButtonAccessible::AccDoAction(PRUint8 index) +{ + nsIFrame* frame = nsAccessible::GetBoundsFrame(); + nsCOMPtr context; + GetPresContext(context); + if (!context) + return NS_ERROR_FAILURE; + + frame->FirstChild(context, nsnull, &frame); +#ifdef DEBUG + if (! nsAccessible::IsCorrectFrameType(frame, nsLayoutAtoms::blockFrame)) + return NS_ERROR_FAILURE; +#endif + + frame->GetNextSibling(&frame); +#ifdef DEBUG + if (! nsAccessible::IsCorrectFrameType(frame, nsLayoutAtoms::gfxButtonControlFrame)) + return NS_ERROR_FAILURE; +#endif + + nsCOMPtr content; + frame->GetContent(getter_AddRefs(content)); + + // We only have one action, click. Any other index is meaningless(wrong) + if (index == eAction_Click) { + nsCOMPtr element(do_QueryInterface(content)); + if (element) + { + element->Click(); + return NS_OK; + } + return NS_ERROR_FAILURE; + } + return NS_ERROR_INVALID_ARG; +} + +/** + * Our next sibling is an nsHTMLComboboxWindowAccessible object + */ +NS_IMETHODIMP nsHTMLComboboxButtonAccessible::GetAccNextSibling(nsIAccessible **_retval) +{ + nsCOMPtr parent; + GetAccParent(getter_AddRefs(parent)); + + *_retval = new nsHTMLComboboxWindowAccessible(parent, mDOMNode, mPresShell); + if (! *_retval) + return NS_ERROR_OUT_OF_MEMORY; + NS_ADDREF(*_retval); + return NS_OK; +} + +/** + * Our next sibling is an nsHTMLComboboxTextFieldAccessible object + */ +NS_IMETHODIMP nsHTMLComboboxButtonAccessible::GetAccPreviousSibling(nsIAccessible **_retval) +{ + nsCOMPtr parent; + GetAccParent(getter_AddRefs(parent)); + + *_retval = new nsHTMLComboboxTextFieldAccessible(parent, mDOMNode, mPresShell); + if (! *_retval) + return NS_ERROR_FAILURE; + NS_ADDREF(*_retval); + return NS_OK; +} + +/** ----- nsHTMLComboboxWindowAccessible ----- */ + +/** + * Constructor -- cache our parent + */ +nsHTMLComboboxWindowAccessible::nsHTMLComboboxWindowAccessible(nsIAccessible* aParent, + nsIDOMNode* aDOMNode, + nsIWeakReference* aShell): +nsComboboxWindowAccessible(aParent, aDOMNode, aShell) +{ +} + +/** + * Our previous sibling is a nsHTMLComboboxButtonAccessible object + */ +NS_IMETHODIMP nsHTMLComboboxWindowAccessible::GetAccPreviousSibling(nsIAccessible **_retval) +{ + nsCOMPtr parent; + GetAccParent(getter_AddRefs(parent)); + + *_retval = new nsHTMLComboboxButtonAccessible(parent, mDOMNode, mPresShell); + if (! *_retval) + return NS_ERROR_FAILURE; + NS_ADDREF(*_retval); + return NS_OK; +} + +/** + * We only have one child, a list + */ +NS_IMETHODIMP nsHTMLComboboxWindowAccessible::GetAccLastChild(nsIAccessible **_retval) +{ + *_retval = new nsHTMLSelectListAccessible(this, mDOMNode, mPresShell); + if (! *_retval) + return NS_ERROR_FAILURE; + NS_ADDREF(*_retval); + return NS_OK; +} + +/** + * We only have one child, a list + */ +NS_IMETHODIMP nsHTMLComboboxWindowAccessible::GetAccFirstChild(nsIAccessible **_retval) +{ + *_retval = new nsHTMLSelectListAccessible(this, mDOMNode, mPresShell); + if (! *_retval) + return NS_ERROR_FAILURE; + NS_ADDREF(*_retval); + return NS_OK; +} + diff --git a/mozilla/accessible/src/nsHTMLSelectAccessible.h b/mozilla/accessible/src/nsHTMLSelectAccessible.h index 355abef2763..851c5edb044 100644 --- a/mozilla/accessible/src/nsHTMLSelectAccessible.h +++ b/mozilla/accessible/src/nsHTMLSelectAccessible.h @@ -39,49 +39,171 @@ #ifndef __nsHTMLSelectAccessible_h__ #define __nsHTMLSelectAccessible_h__ -#include "nsAccessible.h" #include "nsCOMPtr.h" -#include "nsIAtom.h" #include "nsIAccessibleSelectable.h" +#include "nsIDOMNode.h" +#include "nsIWeakReference.h" +#include "nsSelectAccessible.h" -class nsHTMLSelectAccessible : public nsAccessible, - public nsIAccessibleSelectable +/** + * Selects, Listboxes and Comboboxes, are made up of a number of different + * widgets, some of which are shared between the two. This file contains + * all of the widgets for both of the Selects, for HTML only. Some of them + * extend classes from nsSelectAccessible.cpp, which contains base classes + * that are also extended by the XUL Select Accessibility support. + * + * Listbox: + * - nsHTMLListboxAccessible + * - nsHTMLSelctListAccessible + * - nsHTMLSelectOptionAccessible + * + * Comboboxes: + * - nsHTMLComboboxAccessilbe + * - nsHTMLComboboxTextFieldAccessible + * - nsHTMLComboboxButtonAccessible + * - nsHTMLComboboxWindowAccessilbe + * - nsHTMLSelectListAccessible + * - nsHTMLSelectOptionAccessible(s) + */ + +/** ------------------------------------------------------ */ +/** First, the common widgets */ +/** ------------------------------------------------------ */ + +/* + * The list that contains all the options in the select. + */ +class nsHTMLSelectListAccessible : public nsSelectListAccessible +{ +public: + + nsHTMLSelectListAccessible(nsIAccessible* aParent, nsIDOMNode* aDOMNode, nsIWeakReference* aShell); + virtual ~nsHTMLSelectListAccessible() {} + + /* ----- nsIAccessible ----- */ + NS_IMETHOD GetAccState(PRUint32 *_retval); + NS_IMETHOD GetAccLastChild(nsIAccessible **_retval); + NS_IMETHOD GetAccFirstChild(nsIAccessible **_retval); + +}; + +/* + * Options inside the select, contained within the list + */ +class nsHTMLSelectOptionAccessible : public nsSelectOptionAccessible +{ +public: + + nsHTMLSelectOptionAccessible(nsIAccessible* aParent, nsIDOMNode* aDOMNode, nsIWeakReference* aShell); + virtual ~nsHTMLSelectOptionAccessible() {} + + /* ----- nsIAccessible ----- */ + NS_IMETHOD GetAccState(PRUint32 *_retval); + NS_IMETHOD GetAccNextSibling(nsIAccessible **_retval); + NS_IMETHOD GetAccPreviousSibling(nsIAccessible **_retval); + + static nsresult GetFocusedOptionNode(nsIWeakReference *aPresShell, nsIDOMNode *aListNode, nsCOMPtr& aFocusedOptionNode); + +}; + +/** ------------------------------------------------------ */ +/** Secondly, the Listbox widget */ +/** ------------------------------------------------------ */ + +/* + * A class the represents the HTML Listbox widget. + */ +class nsHTMLListboxAccessible : public nsListboxAccessible, + public nsIAccessibleSelectable { public: NS_DECL_ISUPPORTS_INHERITED NS_DECL_NSIACCESSIBLESELECTABLE - nsHTMLSelectAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell); - virtual ~nsHTMLSelectAccessible() {} + nsHTMLListboxAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell); + virtual ~nsHTMLListboxAccessible() {} + /* ----- nsIAccessible ----- */ NS_IMETHOD GetAccLastChild(nsIAccessible **_retval); NS_IMETHOD GetAccFirstChild(nsIAccessible **_retval); - NS_IMETHOD GetAccRole(PRUint32 *_retval); NS_IMETHOD GetAccValue(nsAWritableString& _retval); - NS_IMETHOD GetAccChildCount(PRInt32 *_retval); -// helper method to verify frames - static PRBool IsCorrectFrame( nsIFrame* aFrame, nsIAtom* aAtom ); +}; + +/** ------------------------------------------------------ */ +/** Finally, the Combobox widgets */ +/** ------------------------------------------------------ */ + +/* + * A class the represents the HTML Combobox widget. + */ +class nsHTMLComboboxAccessible : public nsComboboxAccessible +{ +public: + + nsHTMLComboboxAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell); + virtual ~nsHTMLComboboxAccessible() {} + + /* ----- nsIAccessible ----- */ + NS_IMETHOD GetAccLastChild(nsIAccessible **_retval); + NS_IMETHOD GetAccFirstChild(nsIAccessible **_retval); + NS_IMETHOD GetAccValue(nsAWritableString& _retval); }; /* - * Each option in the Select. These are in the nsListAccessible + * A class the represents the text field in the Select to the left + * of the drop down button */ -class nsHTMLSelectOptionAccessible : public nsLeafAccessible +class nsHTMLComboboxTextFieldAccessible : public nsComboboxTextFieldAccessible { public: - nsHTMLSelectOptionAccessible(nsIAccessible* aParent, nsIDOMNode* aDOMNode, nsIWeakReference* aShell); + nsHTMLComboboxTextFieldAccessible(nsIAccessible* aParent, nsIDOMNode* aDOMNode, nsIWeakReference* aShell); + virtual ~nsHTMLComboboxTextFieldAccessible() {} - NS_IMETHOD GetAccParent(nsIAccessible **_retval); - NS_IMETHOD GetAccRole(PRUint32 *_retval); + /* ----- nsIAccessible ----- */ NS_IMETHOD GetAccNextSibling(nsIAccessible **_retval); - NS_IMETHOD GetAccPreviousSibling(nsIAccessible **_retval); - NS_IMETHOD GetAccName(nsAWritableString& _retval); - nsCOMPtr mParent; }; +/** + * A class that represents the button inside the Select to the + * right of the text field + */ +class nsHTMLComboboxButtonAccessible : public nsComboboxButtonAccessible +{ +public: + + nsHTMLComboboxButtonAccessible(nsIAccessible* aParent, nsIDOMNode* aDOMNode, nsIWeakReference* aShell); + virtual ~nsHTMLComboboxButtonAccessible() {} + + /* ----- nsIAccessible ----- */ + NS_IMETHOD GetAccNextSibling(nsIAccessible **_retval); + NS_IMETHOD GetAccPreviousSibling(nsIAccessible **_retval); + NS_IMETHOD AccDoAction(PRUint8 index); + +}; + +/* + * A class that represents the window that lives to the right + * of the drop down button inside the Select. This is the window + * that is made visible when the button is pressed. + */ +class nsHTMLComboboxWindowAccessible : public nsComboboxWindowAccessible +{ +public: + + nsHTMLComboboxWindowAccessible(nsIAccessible* aParent, nsIDOMNode* aDOMNode, nsIWeakReference* aShell); + virtual ~nsHTMLComboboxWindowAccessible() {} + + /* ----- nsIAccessible ----- */ + NS_IMETHOD GetAccPreviousSibling(nsIAccessible **_retval); + NS_IMETHOD GetAccLastChild(nsIAccessible **_retval); + NS_IMETHOD GetAccFirstChild(nsIAccessible **_retval); + +}; + + #endif diff --git a/mozilla/accessible/src/nsHTMLSelectListAccessible.cpp b/mozilla/accessible/src/nsHTMLSelectListAccessible.cpp deleted file mode 100644 index 202b4b73cde..00000000000 --- a/mozilla/accessible/src/nsHTMLSelectListAccessible.cpp +++ /dev/null @@ -1,328 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: NPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Netscape 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/NPL/ - * - * 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): - * Original Author: Eric Vaughan (evaughan@netscape.com) - * Contributor(s): John Gaunt (jgaunt@netscape.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 - * 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 NPL, 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 NPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#include "nsHTMLSelectListAccessible.h" - -#include "nsRootAccessible.h" -#include "nsCOMPtr.h" -#include "nsLayoutAtoms.h" -#include "nsIAtom.h" -#include "nsIFrame.h" -#include "nsISelectControlFrame.h" -#include "nsIDOMHTMLOptionElement.h" -#include "nsIDOMHTMLSelectElement.h" -#include "nsIDOMHTMLCollection.h" -#include "nsIListControlFrame.h" - -/** ----- nsHTMLSelectListAccessible ----- */ - -/** - * - */ -nsHTMLSelectListAccessible::nsHTMLSelectListAccessible(nsIAccessible* aParent, - nsIDOMNode* aDOMNode, - nsIWeakReference* aShell) - :nsAccessible(aDOMNode, aShell) -{ - mParent = aParent; -} - -/** - * - */ -NS_IMETHODIMP nsHTMLSelectListAccessible::AccGetBounds(PRInt32 *x, PRInt32 *y, PRInt32 *width, PRInt32 *height) -{ - return mParent->AccGetBounds(x,y,width,height); -} - -/** - * - */ -NS_IMETHODIMP nsHTMLSelectListAccessible::GetAccParent(nsIAccessible **_retval) -{ - *_retval = mParent; - NS_ADDREF(*_retval); - return NS_OK; -} - -/** - * - */ -NS_IMETHODIMP nsHTMLSelectListAccessible::GetAccRole(PRUint32 *_retval) -{ - *_retval = ROLE_LIST; - return NS_OK; -} - -/** - * - */ -NS_IMETHODIMP nsHTMLSelectListAccessible::GetAccPreviousSibling(nsIAccessible **_retval) -{ - *_retval = nsnull; - return NS_OK; -} - -/** - * - */ -NS_IMETHODIMP nsHTMLSelectListAccessible::GetAccNextSibling(nsIAccessible **_retval) -{ - *_retval = nsnull; - return NS_OK; -} - -/** - * - */ -NS_IMETHODIMP nsHTMLSelectListAccessible::GetAccLastChild(nsIAccessible **_retval) -{ - nsCOMPtr last; - mDOMNode->GetLastChild(getter_AddRefs(last)); - - *_retval = new nsHTMLSelectOptionAccessible(this, last, mPresShell); - if ( ! *_retval ) - return NS_ERROR_FAILURE; - NS_ADDREF(*_retval); - return NS_OK; -} - -/** - * - */ -NS_IMETHODIMP nsHTMLSelectListAccessible::GetAccFirstChild(nsIAccessible **_retval) -{ - nsCOMPtr first; - mDOMNode->GetFirstChild(getter_AddRefs(first)); - - *_retval = new nsHTMLSelectOptionAccessible(this, first, mPresShell); - if ( ! *_retval ) - return NS_ERROR_FAILURE; - NS_ADDREF(*_retval); - return NS_OK; -} - -/** - * As a nsHTMLSelectListAccessible we can have the following states: - * STATE_MULTISELECTABLE - * STATE_EXTSELECTABLE - * no STATE_FOCUSED! -- can't be focused, options are focused instead - * no STATE_FOCUSABLE! -- can't be focused, options are focused instead - */ -NS_IMETHODIMP nsHTMLSelectListAccessible::GetAccState(PRUint32 *_retval) -{ - nsCOMPtr select (do_QueryInterface(mDOMNode)); - if ( select ) { - PRBool multiple; - select->GetMultiple(&multiple); - if ( multiple ) - *_retval |= STATE_MULTISELECTABLE | STATE_EXTSELECTABLE; - } - - return NS_OK; -} - - -/** ----- nsHTMLSelectOptionAccessible ----- */ - -/** - * - */ -nsHTMLSelectOptionAccessible::nsHTMLSelectOptionAccessible(nsIAccessible* aParent, nsIDOMNode* aDOMNode, nsIWeakReference* aShell): -nsLeafAccessible(aDOMNode, aShell) -{ - mParent = aParent; -} - -/** - * - */ -NS_IMETHODIMP nsHTMLSelectOptionAccessible::GetAccRole(PRUint32 *_retval) -{ - *_retval = ROLE_LISTITEM; - return NS_OK; -} - -/** - * - */ -NS_IMETHODIMP nsHTMLSelectOptionAccessible::GetAccParent(nsIAccessible **_retval) -{ - *_retval = mParent; - NS_IF_ADDREF(*_retval); - return NS_OK; -} - -/** - * - */ -NS_IMETHODIMP nsHTMLSelectOptionAccessible::GetAccNextSibling(nsIAccessible **_retval) -{ - *_retval = nsnull; - - nsCOMPtr next; - mDOMNode->GetNextSibling(getter_AddRefs(next)); - - if (next) { - *_retval = new nsHTMLSelectOptionAccessible(mParent, next, mPresShell); - if ( ! *_retval ) - return NS_ERROR_FAILURE; - NS_ADDREF(*_retval); - } - - return NS_OK; -} - -/** - * - */ -NS_IMETHODIMP nsHTMLSelectOptionAccessible::GetAccPreviousSibling(nsIAccessible **_retval) -{ - *_retval = nsnull; - - nsCOMPtr prev; - mDOMNode->GetPreviousSibling(getter_AddRefs(prev)); - - if (prev) { - *_retval = new nsHTMLSelectOptionAccessible(mParent, prev, mPresShell); - if ( ! *_retval ) - return NS_ERROR_FAILURE; - NS_ADDREF(*_retval); - } - - return NS_OK; -} - -/** - * - */ -NS_IMETHODIMP nsHTMLSelectOptionAccessible::GetAccName(nsAWritableString& _retval) -{ - nsCOMPtr content (do_QueryInterface(mDOMNode)); - if (!content) { - return NS_ERROR_FAILURE; - } - - nsAutoString option; - nsresult rv = AppendFlatStringFromSubtree(content, &option); - if (NS_SUCCEEDED(rv)) { - // Temp var needed until CompressWhitespace built for nsAWritableString - option.CompressWhitespace(); - _retval.Assign(option); - } - return rv; -} - -/** - * As a nsHTMLSelectOptionAccessible we can have the following states: - * STATE_SELECTABLE - * STATE_SELECTED - * STATE_FOCUSED - * STATE_FOCUSABLE - * STATE_INVISIBLE // not implemented yet - */ -NS_IMETHODIMP nsHTMLSelectOptionAccessible::GetAccState(PRUint32 *_retval) -{ - // this sets either STATE_FOCUSED or 0 (nsAccessible::GetAccState() doesn't know about list options) - *_retval = 0; - nsCOMPtr focusedOptionNode, parentNode; - mParent->AccGetDOMNode(getter_AddRefs(parentNode)); - GetFocusedOptionNode(mPresShell, parentNode, focusedOptionNode); - if (focusedOptionNode == mDOMNode) - *_retval |= STATE_FOCUSED; - - // Are we selected? - nsCOMPtr option (do_QueryInterface(mDOMNode)); - if ( option ) { - PRBool isSelected = PR_FALSE; - option->GetSelected(&isSelected); - if ( isSelected ) - *_retval |= STATE_SELECTED; - } - - *_retval |= STATE_SELECTABLE | STATE_FOCUSABLE; - - return NS_OK; -} - -nsresult nsHTMLSelectOptionAccessible::GetFocusedOptionNode(nsIWeakReference *aPresShell, - nsIDOMNode *aListNode, - nsCOMPtr& aFocusedOptionNode) -{ - NS_ASSERTION(aListNode, "Called GetFocusedOptionNode without a valid list node"); - nsCOMPtr shell(do_QueryReferent(aPresShell)); - if (!shell) - return NS_ERROR_FAILURE; - - nsIFrame *frame = nsnull; - nsCOMPtr content(do_QueryInterface(aListNode)); - shell->GetPrimaryFrameFor(content, &frame); - - nsresult rv; - nsCOMPtr listFrame(do_QueryInterface(frame, &rv)); - if (NS_FAILED(rv)) - return rv; // How can list content not have a list frame? - NS_ASSERTION(listFrame, "We don't have a list frame, but rv returned a success code."); - - // Get what's focused by asking frame for "selected item". - // Don't use DOM method of getting selected item, which instead gives *first* selected option - PRInt32 focusedOptionIndex = 0; - rv = listFrame->GetSelectedIndex(&focusedOptionIndex); - - nsCOMPtr options; - - // Get options - if (NS_SUCCEEDED(rv)) { - nsCOMPtr selectElement(do_QueryInterface(aListNode)); - NS_ASSERTION(selectElement, "No select element where it should be"); - rv = selectElement->GetOptions(getter_AddRefs(options)); - } - - // Either use options and focused index, or default to list node itself - if (NS_SUCCEEDED(rv) && options && focusedOptionIndex >= 0) // Something is focused - rv = options->Item(focusedOptionIndex, getter_AddRefs(aFocusedOptionNode)); - else { // If no options in list or focusedOptionIndex <0, then we are not focused on an item - aFocusedOptionNode = aListNode; // return normal target content - rv = NS_OK; - } - - return rv; -} - diff --git a/mozilla/accessible/src/nsHTMLTextAccessible.cpp b/mozilla/accessible/src/nsHTMLTextAccessible.cpp index b13dddb2960..85957af981c 100644 --- a/mozilla/accessible/src/nsHTMLTextAccessible.cpp +++ b/mozilla/accessible/src/nsHTMLTextAccessible.cpp @@ -38,16 +38,6 @@ * ***** END LICENSE BLOCK ***** */ #include "nsHTMLTextAccessible.h" -#include "nsWeakReference.h" -#include "nsIFrame.h" -#include "nsILink.h" -#include "nsILinkHandler.h" -#include "nsISelection.h" -#include "nsISelectionController.h" -#include "nsIPresContext.h" -#include "nsReadableUtils.h" -#include "nsIDOMXULDescriptionElement.h" -#include "nsIDOMXULLabelElement.h" nsHTMLTextAccessible::nsHTMLTextAccessible(nsIDOMNode* aDomNode, nsIWeakReference* aShell): nsTextAccessible(aDomNode, aShell) diff --git a/mozilla/accessible/src/nsHTMLTextAccessible.h b/mozilla/accessible/src/nsHTMLTextAccessible.h index 391689df547..cbd8ce226da 100644 --- a/mozilla/accessible/src/nsHTMLTextAccessible.h +++ b/mozilla/accessible/src/nsHTMLTextAccessible.h @@ -39,8 +39,7 @@ #ifndef _nsHTMLTextAccessible_H_ #define _nsHTMLTextAccessible_H_ -#include "nsAccessible.h" -#include "nsBaseWidgetAccessible.h" +#include "nsFormControlAccessible.h" class nsIWeakReference; diff --git a/mozilla/accessible/src/nsRootAccessible.cpp b/mozilla/accessible/src/nsRootAccessible.cpp index a7e4c462302..f5c441e1b98 100644 --- a/mozilla/accessible/src/nsRootAccessible.cpp +++ b/mozilla/accessible/src/nsRootAccessible.cpp @@ -68,7 +68,7 @@ #include "nsXPIDLString.h" #include "nsIAccessibilityService.h" #include "nsIServiceManager.h" -#include "nsHTMLSelectListAccessible.h" +#include "nsHTMLSelectAccessible.h" #include "nsIDOMHTMLSelectElement.h" #include "nsIWebProgress.h" #include "nsCURILoader.h" diff --git a/mozilla/accessible/src/nsRootAccessible.h b/mozilla/accessible/src/nsRootAccessible.h index f194b938cdd..e3326ebf5f0 100644 --- a/mozilla/accessible/src/nsRootAccessible.h +++ b/mozilla/accessible/src/nsRootAccessible.h @@ -96,7 +96,6 @@ class nsRootAccessible : public nsAccessible, NS_IMETHOD GetAccState(PRUint32 *aAccState); // ----- nsIAccessibleEventReceiver ------------------- - NS_IMETHOD AddAccessibleEventListener(nsIAccessibleEventListener *aListener); NS_IMETHOD RemoveAccessibleEventListener(); diff --git a/mozilla/accessible/src/nsSelectAccessible.cpp b/mozilla/accessible/src/nsSelectAccessible.cpp new file mode 100644 index 00000000000..1653617a817 --- /dev/null +++ b/mozilla/accessible/src/nsSelectAccessible.cpp @@ -0,0 +1,680 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: NPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Netscape 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/NPL/ + * + * 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): + * Original Author: Eric Vaughan (evaughan@netscape.com) + * Contributor(s): John Gaunt (jgaunt@netscape.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 + * 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 NPL, 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 NPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsCOMPtr.h" +#include "nsFormControlAccessible.h" +#include "nsIAtom.h" +#include "nsIComboboxControlFrame.h" +#include "nsIDOMEventReceiver.h" +#include "nsIDOMHTMLCollection.h" +#include "nsIDOMHTMLOptionElement.h" +#include "nsIDOMHTMLSelectElement.h" +#include "nsIFrame.h" +#include "nsIListControlFrame.h" +#include "nsISelectControlFrame.h" +#include "nsLayoutAtoms.h" +#include "nsRootAccessible.h" +#include "nsSelectAccessible.h" + +/** ------------------------------------------------------ */ +/** First, the common widgets */ +/** ------------------------------------------------------ */ + +/** Constructor -- cache our parent */ +nsSelectListAccessible::nsSelectListAccessible(nsIAccessible* aParent, + nsIDOMNode* aDOMNode, + nsIWeakReference* aShell) +:nsAccessible(aDOMNode, aShell) +{ + mParent = aParent; +} + +/** Return our parents bounds */ +NS_IMETHODIMP nsSelectListAccessible::AccGetBounds(PRInt32 *x, PRInt32 *y, PRInt32 *width, PRInt32 *height) +{ + return mParent->AccGetBounds(x,y,width,height); +} + +/** Return our cached parent */ +NS_IMETHODIMP nsSelectListAccessible::GetAccParent(nsIAccessible **_retval) +{ + *_retval = mParent; + NS_ADDREF(*_retval); + return NS_OK; +} + +/** We are a list */ +NS_IMETHODIMP nsSelectListAccessible::GetAccRole(PRUint32 *_retval) +{ + *_retval = ROLE_LIST; + return NS_OK; +} + +/** We are an only child */ +NS_IMETHODIMP nsSelectListAccessible::GetAccPreviousSibling(nsIAccessible **_retval) +{ + *_retval = nsnull; + return NS_OK; +} + +/** We are an only child */ +NS_IMETHODIMP nsSelectListAccessible::GetAccNextSibling(nsIAccessible **_retval) +{ + *_retval = nsnull; + return NS_OK; +} + +/** + * nsSelectOptionAccessible + */ + +/** Constructor -- cache our parent */ +nsSelectOptionAccessible::nsSelectOptionAccessible(nsIAccessible* aParent, nsIDOMNode* aDOMNode, nsIWeakReference* aShell): +nsLeafAccessible(aDOMNode, aShell) +{ + mParent = aParent; +} + +/** We are a ListItem */ +NS_IMETHODIMP nsSelectOptionAccessible::GetAccRole(PRUint32 *_retval) +{ + *_retval = ROLE_LISTITEM; + return NS_OK; +} + +/** Return our cached parent */ +NS_IMETHODIMP nsSelectOptionAccessible::GetAccParent(nsIAccessible **_retval) +{ + *_retval = mParent; + NS_IF_ADDREF(*_retval); + return NS_OK; +} + +/** + * Get our Name from our Content's subtree + */ +NS_IMETHODIMP nsSelectOptionAccessible::GetAccName(nsAWritableString& _retval) +{ + nsCOMPtr content (do_QueryInterface(mDOMNode)); + if (!content) { + return NS_ERROR_FAILURE; + } + + nsAutoString option; + nsresult rv = AppendFlatStringFromSubtree(content, &option); + if (NS_SUCCEEDED(rv)) { + // Temp var needed until CompressWhitespace built for nsAWritableString + option.CompressWhitespace(); + _retval.Assign(option); + } + return rv; +} + +/** ------------------------------------------------------ */ +/** Secondly, the Listbox widget */ +/** ------------------------------------------------------ */ + +/** ----- nsListboxAccessible ----- */ + +/** Constructor */ +nsListboxAccessible::nsListboxAccessible(nsIDOMNode* aDOMNode, + nsIWeakReference* aShell): +nsAccessible(aDOMNode, aShell) +{ +} + +/** 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; +} + +/** ------------------------------------------------------ */ +/** 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 */ +nsComboboxTextFieldAccessible::nsComboboxTextFieldAccessible(nsIAccessible* aParent, + nsIDOMNode* aDOMNode, + nsIWeakReference* aShell): +nsLeafAccessible(aDOMNode, aShell) +{ + mParent = aParent; +} + +/** + * Currently gets the text from the first option, needs to check for selection + * and then return that text. + * Walks the Frame tree and checks for proper frames. + */ +NS_IMETHODIMP nsComboboxTextFieldAccessible::GetAccValue(nsAWritableString& _retval) +{ + nsIFrame* frame = nsAccessible::GetBoundsFrame(); + nsCOMPtr context; + GetPresContext(context); + if (!frame || !context) + return NS_ERROR_FAILURE; + + frame->FirstChild(context, nsnull, &frame); +#ifdef DEBUG + if (! nsAccessible::IsCorrectFrameType(frame, nsLayoutAtoms::blockFrame)) + return NS_ERROR_FAILURE; +#endif + + frame->FirstChild(context, nsnull, &frame); +#ifdef DEBUG + if (! nsAccessible::IsCorrectFrameType(frame, nsLayoutAtoms::textFrame)) + return NS_ERROR_FAILURE; +#endif + + nsCOMPtr content; + frame->GetContent(getter_AddRefs(content)); + + if (!content) + return NS_ERROR_FAILURE; + + AppendFlatStringFromSubtree(content, &_retval); + + return NS_OK; +} + +/** + * Gets the bounds for the BlockFrame. + * Walks the Frame tree and checks for proper frames. + */ +void nsComboboxTextFieldAccessible::GetBounds(nsRect& aBounds, nsIFrame** aBoundingFrame) +{ + // get our first child's frame + nsIFrame* frame = nsAccessible::GetBoundsFrame(); + nsCOMPtr context; + GetPresContext(context); + if (!frame || !context) + return; + + frame->FirstChild(context, nsnull, aBoundingFrame); + frame->FirstChild(context, nsnull, &frame); +#ifdef DEBUG + if (! nsAccessible::IsCorrectFrameType(frame, nsLayoutAtoms::blockFrame)) + return; +#endif + + frame->GetRect(aBounds); +} + +/** Return our cached parent */ +NS_IMETHODIMP nsComboboxTextFieldAccessible::GetAccParent(nsIAccessible **_retval) +{ + *_retval = mParent; + NS_IF_ADDREF(*_retval); + return NS_OK; +} + +/** + * We are the first child of our parent, no previous sibling + */ +NS_IMETHODIMP nsComboboxTextFieldAccessible::GetAccPreviousSibling(nsIAccessible **_retval) +{ + *_retval = nsnull; + return NS_OK; +} + +/** + * Our role is currently only static text, but we should be able to have + * editable text here and we need to check that case. + */ +NS_IMETHODIMP nsComboboxTextFieldAccessible::GetAccRole(PRUint32 *_retval) +{ + *_retval = ROLE_STATICTEXT; + return NS_OK; +} + +/** + * As a nsComboboxTextFieldAccessible we can have the following states: + * STATE_READONLY + * STATE_FOCUSED + * STATE_FOCUSABLE + */ +NS_IMETHODIMP nsComboboxTextFieldAccessible::GetAccState(PRUint32 *_retval) +{ + // Get focus status from base class + nsAccessible::GetAccState(_retval); + + *_retval |= STATE_READONLY | STATE_FOCUSABLE; + + return NS_OK; +} + +/** -----ComboboxButtonAccessible ----- */ + +/** Constructor -- cache our parent */ +nsComboboxButtonAccessible::nsComboboxButtonAccessible(nsIAccessible* aParent, + nsIDOMNode* aDOMNode, + nsIWeakReference* aShell): +nsLeafAccessible(aDOMNode, aShell) +{ + mParent = aParent; +} + +/** Just one action ( click ). */ +NS_IMETHODIMP nsComboboxButtonAccessible::GetAccNumActions(PRUint8 *_retval) +{ + *_retval = eSingle_Action; + return NS_OK; +} + +/** + * Gets the bounds for the gfxButtonControlFrame. + * Walks the Frame tree and checks for proper frames. + */ +void nsComboboxButtonAccessible::GetBounds(nsRect& aBounds, nsIFrame** aBoundingFrame) +{ + // get our second child's frame + nsIFrame* frame = nsAccessible::GetBoundsFrame(); + nsCOMPtr context; + GetPresContext(context); + if (!context) + return; + + frame->FirstChild(context, nsnull, &frame); +#ifdef DEBUG + if (! nsAccessible::IsCorrectFrameType(frame, nsLayoutAtoms::blockFrame)) + return; +#endif + + frame->GetNextSibling(aBoundingFrame); + frame->GetNextSibling(&frame); +#ifdef DEBUG + if (! nsAccessible::IsCorrectFrameType(frame, nsLayoutAtoms::gfxButtonControlFrame)) + return; +#endif + + frame->GetRect(aBounds); +} + +/** We are a button. */ +NS_IMETHODIMP nsComboboxButtonAccessible::GetAccRole(PRUint32 *_retval) +{ + *_retval = ROLE_PUSHBUTTON; + return NS_OK; +} + +/** Return our cached parent */ +NS_IMETHODIMP nsComboboxButtonAccessible::GetAccParent(nsIAccessible **_retval) +{ + *_retval = mParent; + NS_IF_ADDREF(*_retval); + return NS_OK; +} + +/** + * Gets the name from GetAccActionName() + */ +NS_IMETHODIMP nsComboboxButtonAccessible::GetAccName(nsAWritableString& _retval) +{ + return GetAccActionName(eAction_Click, _retval); +} + +/** + * Our action name is the reverse of our state: + * if we are closed -> open is our name. + * if we are open -> closed is our name. + * Uses the frame to get the state, updated on every click + */ +NS_IMETHODIMP nsComboboxButtonAccessible::GetAccActionName(PRUint8 index, nsAWritableString& _retval) +{ + PRBool isOpen = PR_FALSE; + nsIFrame *boundsFrame = GetBoundsFrame(); + nsIComboboxControlFrame* comboFrame; + boundsFrame->QueryInterface(NS_GET_IID(nsIComboboxControlFrame), (void**)&comboFrame); + if (!comboFrame) + return NS_ERROR_FAILURE; + comboFrame->IsDroppedDown(&isOpen); + if (isOpen) + _retval = NS_LITERAL_STRING("Close"); + else + _retval = NS_LITERAL_STRING("Open"); + + return NS_OK; +} + +/** + * As a nsComboboxButtonAccessible we can have the following states: + * STATE_PRESSED + * STATE_FOCUSED + * STATE_FOCUSABLE + */ +NS_IMETHODIMP nsComboboxButtonAccessible::GetAccState(PRUint32 *_retval) +{ + // Get focus status from base class + nsAccessible::GetAccState(_retval); + + // we are open or closed --> pressed or not + PRBool isOpen = PR_FALSE; + nsIFrame *boundsFrame = GetBoundsFrame(); + nsIComboboxControlFrame* comboFrame; + boundsFrame->QueryInterface(NS_GET_IID(nsIComboboxControlFrame), (void**)&comboFrame); + if (!comboFrame) + return NS_ERROR_FAILURE; + comboFrame->IsDroppedDown(&isOpen); + if (isOpen) + *_retval |= STATE_PRESSED; + + *_retval |= STATE_FOCUSABLE; + + return NS_OK; +} + +/** ----- nsComboboxWindowAccessible ----- */ + +/** + * Constructor -- cache our parent + */ +nsComboboxWindowAccessible::nsComboboxWindowAccessible(nsIAccessible* aParent, + nsIDOMNode* aDOMNode, + nsIWeakReference* aShell): +nsAccessible(aDOMNode, aShell) +{ + mParent = aParent; +} + +/** + * As a nsComboboxWindowAccessible we can have the following states: + * STATE_FOCUSED + * STATE_FOCUSABLE + * STATE_INVISIBLE + * STATE_FLOATING + */ +NS_IMETHODIMP nsComboboxWindowAccessible::GetAccState(PRUint32 *_retval) +{ + // Get focus status from base class + nsAccessible::GetAccState(_retval); + + // we are open or closed + PRBool isOpen = PR_FALSE; + nsIFrame *boundsFrame = GetBoundsFrame(); + nsIComboboxControlFrame* comboFrame = nsnull; + boundsFrame->QueryInterface(NS_GET_IID(nsIComboboxControlFrame), (void**)&comboFrame); + if (!comboFrame) + return NS_ERROR_FAILURE; + comboFrame->IsDroppedDown(&isOpen); + if (! isOpen) + *_retval |= STATE_INVISIBLE; + + *_retval |= STATE_FOCUSABLE | STATE_FLOATING; + + return NS_OK; +} + +/** We are a window */ +NS_IMETHODIMP nsComboboxWindowAccessible::GetAccRole(PRUint32 *_retval) +{ + *_retval = ROLE_WINDOW; + return NS_OK; +} + +/** Return our cached parent */ +NS_IMETHODIMP nsComboboxWindowAccessible::GetAccParent(nsIAccessible **_retval) +{ + *_retval = mParent; + NS_IF_ADDREF(*_retval); + return NS_OK; +} + +/** + * We are the last sibling of our parent. + */ +NS_IMETHODIMP nsComboboxWindowAccessible::GetAccNextSibling(nsIAccessible **_retval) +{ + *_retval = nsnull; + return NS_OK; +} + +/** + * We only have one child, a list + */ +NS_IMETHODIMP nsComboboxWindowAccessible::GetAccChildCount(PRInt32 *_retval) +{ + *_retval = 1; + return NS_OK; +} + +/** + * Gets the bounds for the areaFrame. + * Walks the Frame tree and checks for proper frames. + */ +void nsComboboxWindowAccessible::GetBounds(nsRect& aBounds, nsIFrame** aBoundingFrame) +{ + // get our first option + nsCOMPtr child; + mDOMNode->GetFirstChild(getter_AddRefs(child)); + + // now get its frame + nsCOMPtr shell(do_QueryReferent(mPresShell)); + if (!shell) { + *aBoundingFrame = nsnull; + return; + } + + nsIFrame* frame = nsnull; + nsCOMPtr content(do_QueryInterface(child)); + shell->GetPrimaryFrameFor(content, &frame); +#ifdef DEBUG + if (! nsAccessible::IsCorrectFrameType(frame, nsLayoutAtoms::blockFrame)) + return; +#endif + + frame->GetParent(aBoundingFrame); + frame->GetParent(&frame); +#ifdef DEBUG + if (! nsAccessible::IsCorrectFrameType(frame, nsLayoutAtoms::areaFrame)) + return; +#endif + + frame->GetRect(aBounds); +} + diff --git a/mozilla/accessible/src/nsSelectAccessible.h b/mozilla/accessible/src/nsSelectAccessible.h new file mode 100644 index 00000000000..58e44bd892c --- /dev/null +++ b/mozilla/accessible/src/nsSelectAccessible.h @@ -0,0 +1,237 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: NPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Netscape 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/NPL/ + * + * 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): + * Original Author: Eric Vaughan (evaughan@netscape.com) + * Contributor(s): John Gaunt (jgaunt@netscape.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 + * 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 NPL, 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 NPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef __nsSelectAccessible_h__ +#define __nsSelectAccessible_h__ + +#include "nsBaseWidgetAccessible.h" +#include "nsIAccessibleSelectable.h" +#include "nsIDOMXULListener.h" + +/** ------------------------------------------------------ */ +/** First, the common widgets */ +/** ------------------------------------------------------ */ + +/** + * The list that contains all the options in the select. + */ +class nsSelectListAccessible : public nsAccessible +{ +public: + + nsSelectListAccessible(nsIAccessible* aParent, nsIDOMNode* aDOMNode, nsIWeakReference* aShell); + virtual ~nsSelectListAccessible() {} + + /* ----- nsIAccessible ----- */ + NS_IMETHOD GetAccParent(nsIAccessible **_retval); + NS_IMETHOD GetAccRole(PRUint32 *_retval); + NS_IMETHOD AccGetBounds(PRInt32 *x, PRInt32 *y, PRInt32 *width, PRInt32 *height); + NS_IMETHOD GetAccNextSibling(nsIAccessible **_retval); + NS_IMETHOD GetAccPreviousSibling(nsIAccessible **_retval); + +protected: + + nsCOMPtr mParent; +}; + +/** + * Options inside the select, contained within the list + */ +class nsSelectOptionAccessible : public nsLeafAccessible +{ +public: + + nsSelectOptionAccessible(nsIAccessible* aParent, nsIDOMNode* aDOMNode, nsIWeakReference* aShell); + virtual ~nsSelectOptionAccessible() {} + + /* ----- nsIAccessible ----- */ + NS_IMETHOD GetAccParent(nsIAccessible **_retval); + NS_IMETHOD GetAccRole(PRUint32 *_retval); + NS_IMETHOD GetAccName(nsAWritableString& _retval); + +protected: + + nsCOMPtr mParent; +}; + +/** ------------------------------------------------------ */ +/** Secondly, the Listbox widget */ +/** ------------------------------------------------------ */ + +/** + * A class that represents the Listbox widget. + */ +class nsListboxAccessible : public nsAccessible +{ +public: + + 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 + */ +class nsComboboxTextFieldAccessible : public nsLeafAccessible +{ +public: + + nsComboboxTextFieldAccessible(nsIAccessible* aParent, nsIDOMNode* aDOMNode, nsIWeakReference* aShell); + virtual ~nsComboboxTextFieldAccessible() {} + + /* ----- nsIAccessible ----- */ + NS_IMETHOD GetAccPreviousSibling(nsIAccessible **_retval); + NS_IMETHOD GetAccParent(nsIAccessible **_retval); + NS_IMETHOD GetAccRole(PRUint32 *_retval); + NS_IMETHOD GetAccValue(nsAWritableString& _retval); + NS_IMETHOD GetAccState(PRUint32 *_retval); + + virtual void GetBounds(nsRect& aBounds, nsIFrame** aBoundingFrame); + +protected: + + nsCOMPtr mParent; +}; + +/** + * A class that represents the button inside the Select to the + * right of the text field + */ +class nsComboboxButtonAccessible : public nsLeafAccessible +{ +public: + + nsComboboxButtonAccessible(nsIAccessible* aParent, nsIDOMNode* aDOMNode, nsIWeakReference* aShell); + virtual ~nsComboboxButtonAccessible() {} + + /* ----- nsIAccessible ----- */ + NS_IMETHOD GetAccParent(nsIAccessible **_retval); + NS_IMETHOD GetAccName(nsAWritableString& _retval); + NS_IMETHOD GetAccRole(PRUint32 *_retval); + NS_IMETHOD GetAccNumActions(PRUint8 *_retval); + NS_IMETHOD GetAccActionName(PRUint8 index, nsAWritableString& _retval); + NS_IMETHOD GetAccState(PRUint32 *_retval); + + virtual void GetBounds(nsRect& aBounds, nsIFrame** aBoundingFrame); + +protected: + + nsCOMPtr mParent; +}; + +/** + * A class that represents the window that lives to the right + * of the drop down button inside the Select. This is the window + * that is made visible when the button is pressed. + */ +class nsComboboxWindowAccessible : public nsAccessible +{ +public: + + nsComboboxWindowAccessible(nsIAccessible* aParent, nsIDOMNode* aDOMNode, nsIWeakReference* aShell); + virtual ~nsComboboxWindowAccessible() {} + + /* ----- nsIAccessible ----- */ + NS_IMETHOD GetAccParent(nsIAccessible **_retval); + NS_IMETHOD GetAccNextSibling(nsIAccessible **_retval); + NS_IMETHOD GetAccChildCount(PRInt32 *_retval); + NS_IMETHOD GetAccRole(PRUint32 *_retval); + NS_IMETHOD GetAccState(PRUint32 *_retval); + + virtual void GetBounds(nsRect& aBounds, nsIFrame** aBoundingFrame); + +protected: + + nsCOMPtr mParent; +}; + +#endif diff --git a/mozilla/accessible/src/nsXULFormControlAccessible.cpp b/mozilla/accessible/src/nsXULFormControlAccessible.cpp index 41427df2119..dd8cbf92577 100644 --- a/mozilla/accessible/src/nsXULFormControlAccessible.cpp +++ b/mozilla/accessible/src/nsXULFormControlAccessible.cpp @@ -42,175 +42,51 @@ #include "nsIDOMNodeList.h" #include "nsIDOMXULButtonElement.h" #include "nsIDOMXULCheckboxElement.h" +#include "nsIDOMXULDescriptionElement.h" #include "nsIDOMXULDocument.h" +#include "nsIDOMXULLabelElement.h" +#include "nsIDOMXULSelectCntrlEl.h" +#include "nsIDOMXULSelectCntrlItemEl.h" #include "nsReadableUtils.h" #include "nsString.h" #include "nsXULFormControlAccessible.h" -// ----- XUL Form Control accessible -------- - -nsXULFormControlAccessible::nsXULFormControlAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell): -nsLeafAccessible(aNode, aShell) -{ -} - /** - * Checks the label's value first then makes a call to get the - * text from the children if the value is not set. + * XUL Button: can contain arbitrary HTML content */ -NS_IMETHODIMP nsXULFormControlAccessible::AppendLabelText(nsIDOMNode *aLabelNode, nsAWritableString& _retval) -{ - NS_ASSERTION(aLabelNode, "Label Node passed in is null"); - nsCOMPtr labelNode(do_QueryInterface(aLabelNode)); - // label's value="foo" is set - if ( labelNode && NS_SUCCEEDED(labelNode->GetValue(_retval))) { - if (_retval.IsEmpty()) { - // label contains children who define it's text -- possibly HTML - nsCOMPtr content(do_QueryInterface(labelNode)); - if (content) - return AppendFlatStringFromSubtree(content, &_retval); - } - return NS_OK; - } - return NS_ERROR_FAILURE; -} /** - * 3 main cases for Xul Controls to be labeled - * 1 - control contains label="foo" - * 2 - control has, as a child, a label element - * - label has either value="foo" or children - * 3 - non-child label contains control="controlID" - * - label has either value="foo" or children - * Once a label is found, the search is discontinued, so a control - * that has a label child as well as having a label external to - * the control that uses the control="controlID" syntax will use - * the child label for its Name. + * Default Constructor */ -/* wstring getAccName (); */ -NS_IMETHODIMP nsXULFormControlAccessible::GetAccName(nsAWritableString& _retval) -{ - nsresult rv; - nsAutoString label; - - // CASE #1 -- great majority of the cases - nsCOMPtr domElement(do_QueryInterface(mDOMNode)); - NS_ASSERTION(domElement, "No domElement for accessible DOM node!"); - rv = domElement->GetAttribute(NS_LITERAL_STRING("label"), label) ; - - if (NS_FAILED(rv) || label.IsEmpty() ) { - - // CASE #2 ------ label as a child - nsCOMPtrlabelChildren; - NS_ASSERTION(domElement, "No domElement for accessible DOM node!"); - if (NS_SUCCEEDED(rv = domElement->GetElementsByTagName(NS_LITERAL_STRING("label"), getter_AddRefs(labelChildren)))) { - PRUint32 length = 0; - if (NS_SUCCEEDED(rv = labelChildren->GetLength(&length)) && length > 0) { - for (PRUint32 i = 0; i < length; ++i) { - nsCOMPtr child; - if (NS_SUCCEEDED(rv = labelChildren->Item(i, getter_AddRefs(child) ))) { - rv = AppendLabelText(child, label); - } - } - } - } - - if (NS_FAILED(rv) || label.IsEmpty()) { - - // CASE #3 ----- non-child label pointing to control - // XXX jgaunt - // decided to search the parent's children for labels linked to - // this control via the control="controlID" syntax, instead of searching - // the entire document with: - // - // nsCOMPtr doc; - // nsCOMPtr content(do_QueryInterface(mDOMNode)); - // content->GetDocument(*getter_AddRefs(doc)); - // nsCOMPtr xulDoc(do_QueryInterface(doc)); - // if (xulDoc) { - // nsCOMPtrlabelList; - // if (NS_SUCCEEDED(rv = xulDoc->GetElementsByAttribute(NS_LITERAL_STRING("control"), controlID, getter_AddRefs(labelList)))) - // - // This should keep search times down and still get the relevant - // labels. - nsCOMPtr parent; - if (NS_SUCCEEDED(rv = mDOMNode->GetParentNode(getter_AddRefs(parent)))) { - nsCOMPtr xulElement(do_QueryInterface(parent)); - NS_ASSERTION(xulElement, "No xulElement for parent DOM Node!"); - if (xulElement) { - nsAutoString controlID; - nsCOMPtrlabelList; - if (NS_SUCCEEDED(rv = xulElement->GetElementsByAttribute(NS_LITERAL_STRING("control"), controlID, getter_AddRefs(labelList)))) - { - PRUint32 length = 0; - if (NS_SUCCEEDED(rv = labelList->GetLength(&length)) && length > 0) { - for (PRUint32 i = 0; i < length; ++i) { - nsCOMPtr child; - if (NS_SUCCEEDED(rv = labelList->Item(i, getter_AddRefs(child) ))) { - rv = AppendLabelText(child, label); - } - } - } - } - } - } // End of CASE #3 - } // END of CASE #2 - } // END of CASE #1 - - label.CompressWhitespace(); - if (label.IsEmpty()) - return nsAccessible::GetAccName(_retval); - - _retval.Assign(label); - return NS_OK; -} - -/** - * XUL Form controls can be focusable, focused, unavailable, ?protected? - **/ -NS_IMETHODIMP nsXULFormControlAccessible::GetAccState(PRUint32 *_retval) -{ - // Get the focused state from the nsAccessible - nsAccessible::GetAccState(_retval); - - PRBool disabled = PR_FALSE; - nsCOMPtr xulFormElement(do_QueryInterface(mDOMNode)); - if (xulFormElement) - xulFormElement->GetDisabled(&disabled); - - if (disabled) - *_retval |= STATE_UNAVAILABLE; - else - *_retval |= STATE_FOCUSABLE; - - return NS_OK; -} - -// ----- XUL Button: can contain arbitrary HTML content ----- - nsXULButtonAccessible::nsXULButtonAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell): -nsBlockAccessible(aNode, aShell) +nsFormControlAccessible(aNode, aShell) { } -/* PRUint8 getAccNumActions (); */ +/** + * Only one actions available + */ NS_IMETHODIMP nsXULButtonAccessible::GetAccNumActions(PRUint8 *_retval) { - *_retval = 1; + *_retval = eSingle_Action; return NS_OK;; } -/* wstring getAccActionName (in PRUint8 index); */ +/** + * Return the name of our only action + */ NS_IMETHODIMP nsXULButtonAccessible::GetAccActionName(PRUint8 index, nsAWritableString& _retval) { - if (index == 0) { + if (index == eAction_Click) { _retval = NS_LITERAL_STRING("press"); return NS_OK; } return NS_ERROR_INVALID_ARG; } -/* void accDoAction (in PRUint8 index); */ +/** + * Tell the button to do it's action + */ NS_IMETHODIMP nsXULButtonAccessible::AccDoAction(PRUint8 index) { if (index == 0) { @@ -225,57 +101,62 @@ NS_IMETHODIMP nsXULButtonAccessible::AccDoAction(PRUint8 index) return NS_ERROR_INVALID_ARG; } -/* unsigned long getAccRole (); */ +/** + * We are a pushbutton + */ NS_IMETHODIMP nsXULButtonAccessible::GetAccRole(PRUint32 *_retval) { *_retval = ROLE_PUSHBUTTON; return NS_OK; } -/* long getAccState (); */ +/** + * Possible states: focused, focusable, unavailable(disabled) + */ NS_IMETHODIMP nsXULButtonAccessible::GetAccState(PRUint32 *_retval) { - nsAccessible::GetAccState(_retval); + // get focus and disable status from base class + nsFormControlAccessible::GetAccState(_retval); *_retval |= STATE_FOCUSABLE; return NS_OK; } +/** + * XUL checkbox + */ -/* wstring getAccName (); */ -NS_IMETHODIMP nsXULButtonAccessible::GetAccName(nsAWritableString& _retval) -{ - nsCOMPtr buttonElement(do_QueryInterface(mDOMNode)); - if ( buttonElement ) { - return buttonElement->GetLabel(_retval); - } - return NS_ERROR_FAILURE; -} - -// --- XUL checkbox ----- - +/** + * Default Constructor + */ nsXULCheckboxAccessible::nsXULCheckboxAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell): -nsXULFormControlAccessible(aNode, aShell) +nsFormControlAccessible(aNode, aShell) { } -/* unsigned long getAccRole (); */ +/** + * We are a CheckButton + */ NS_IMETHODIMP nsXULCheckboxAccessible::GetAccRole(PRUint32 *_retval) { *_retval = ROLE_CHECKBUTTON; return NS_OK; } -/* PRUint8 getAccNumActions (); */ +/** + * Only one action available + */ NS_IMETHODIMP nsXULCheckboxAccessible::GetAccNumActions(PRUint8 *_retval) { - *_retval = 1; + *_retval = eSingle_Action; return NS_OK; } -/* wstring getAccActionName (in PRUint8 index); */ +/** + * Return the name of our only action + */ NS_IMETHODIMP nsXULCheckboxAccessible::GetAccActionName(PRUint8 index, nsAWritableString& _retval) { - if (index == 0) { // 0 is the magic value for default action + if (index == eAction_Click) { // check or uncheck PRUint32 state; GetAccState(&state); @@ -290,10 +171,12 @@ NS_IMETHODIMP nsXULCheckboxAccessible::GetAccActionName(PRUint8 index, nsAWritab return NS_ERROR_INVALID_ARG; } -/* void accDoAction (in PRUint8 index); */ +/** + * Tell the checkbox to do its only action -- check( or uncheck) itself + */ NS_IMETHODIMP nsXULCheckboxAccessible::AccDoAction(PRUint8 index) { - if (index == 0) { // 0 is the magic value for default action + if (index == eAction_Click) { PRBool checked = PR_FALSE; nsCOMPtr xulCheckboxElement(do_QueryInterface(mDOMNode)); if (xulCheckboxElement) { @@ -306,10 +189,13 @@ NS_IMETHODIMP nsXULCheckboxAccessible::AccDoAction(PRUint8 index) return NS_ERROR_INVALID_ARG; } +/** + * Possible states: focused, focusable, unavailable(disabled), checked + */ NS_IMETHODIMP nsXULCheckboxAccessible::GetAccState(PRUint32 *_retval) { - // Get focus state from parent - nsXULFormControlAccessible::GetAccState(_retval); + // Get focus and disable status from base class + nsFormControlAccessible::GetAccState(_retval); // Determine Checked state PRBool checked = PR_FALSE; diff --git a/mozilla/accessible/src/nsXULFormControlAccessible.h b/mozilla/accessible/src/nsXULFormControlAccessible.h index 8e722e29ddb..6ccff403fd7 100644 --- a/mozilla/accessible/src/nsXULFormControlAccessible.h +++ b/mozilla/accessible/src/nsXULFormControlAccessible.h @@ -41,40 +41,22 @@ #define _nsXULFormControlAccessible_H_ // NOTE: alphabetically ordered -#include "nsAccessible.h" #include "nsBaseWidgetAccessible.h" +#include "nsFormControlAccessible.h" #include "nsHTMLFormControlAccessible.h" -#include "nsIDOMXULLabelElement.h" -/* Accessible for supporting for controls - * supports: - * - walking up to get name from label - * - support basic state - */ -class nsXULFormControlAccessible : public nsLeafAccessible -{ -public: - nsXULFormControlAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell); - NS_IMETHOD GetAccName(nsAWritableString& _retval); - NS_IMETHOD GetAccState(PRUint32 *_retval); - -protected: - NS_IMETHODIMP AppendLabelText(nsIDOMNode *aLabelNode, nsAWritableString& _retval); -}; - -class nsXULButtonAccessible : public nsBlockAccessible +class nsXULButtonAccessible : public nsFormControlAccessible { public: nsXULButtonAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell); NS_IMETHOD GetAccRole(PRUint32 *_retval); - NS_IMETHOD GetAccName(nsAWritableString& _retval); NS_IMETHOD GetAccState(PRUint32 *_retval); NS_IMETHOD GetAccNumActions(PRUint8 *_retval); NS_IMETHOD GetAccActionName(PRUint8 index, nsAWritableString& _retval); NS_IMETHOD AccDoAction(PRUint8 index); }; -class nsXULCheckboxAccessible : public nsXULFormControlAccessible +class nsXULCheckboxAccessible : public nsFormControlAccessible { public: nsXULCheckboxAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell); @@ -86,3 +68,4 @@ public: }; #endif + diff --git a/mozilla/accessible/src/nsXULTextAccessible.cpp b/mozilla/accessible/src/nsXULTextAccessible.cpp index 90de5609af1..72e83b2b5a9 100644 --- a/mozilla/accessible/src/nsXULTextAccessible.cpp +++ b/mozilla/accessible/src/nsXULTextAccessible.cpp @@ -39,7 +39,6 @@ // NOTE: alphabetically ordered #include "nsIDOMXULDescriptionElement.h" -#include "nsIDOMXULLabelElement.h" #include "nsWeakReference.h" #include "nsXULTextAccessible.h" diff --git a/mozilla/accessible/src/nsXULTextAccessible.h b/mozilla/accessible/src/nsXULTextAccessible.h index fad3d2f796e..235345fe562 100644 --- a/mozilla/accessible/src/nsXULTextAccessible.h +++ b/mozilla/accessible/src/nsXULTextAccessible.h @@ -40,8 +40,7 @@ #ifndef _nsXULTextAccessible_H_ #define _nsXULTextAccessible_H_ -#include "nsAccessible.h" -#include "nsBaseWidgetAccessible.h" +#include "nsFormControlAccessible.h" class nsIWeakReference; diff --git a/mozilla/accessible/src/xul/nsXULFormControlAccessible.cpp b/mozilla/accessible/src/xul/nsXULFormControlAccessible.cpp index 41427df2119..dd8cbf92577 100644 --- a/mozilla/accessible/src/xul/nsXULFormControlAccessible.cpp +++ b/mozilla/accessible/src/xul/nsXULFormControlAccessible.cpp @@ -42,175 +42,51 @@ #include "nsIDOMNodeList.h" #include "nsIDOMXULButtonElement.h" #include "nsIDOMXULCheckboxElement.h" +#include "nsIDOMXULDescriptionElement.h" #include "nsIDOMXULDocument.h" +#include "nsIDOMXULLabelElement.h" +#include "nsIDOMXULSelectCntrlEl.h" +#include "nsIDOMXULSelectCntrlItemEl.h" #include "nsReadableUtils.h" #include "nsString.h" #include "nsXULFormControlAccessible.h" -// ----- XUL Form Control accessible -------- - -nsXULFormControlAccessible::nsXULFormControlAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell): -nsLeafAccessible(aNode, aShell) -{ -} - /** - * Checks the label's value first then makes a call to get the - * text from the children if the value is not set. + * XUL Button: can contain arbitrary HTML content */ -NS_IMETHODIMP nsXULFormControlAccessible::AppendLabelText(nsIDOMNode *aLabelNode, nsAWritableString& _retval) -{ - NS_ASSERTION(aLabelNode, "Label Node passed in is null"); - nsCOMPtr labelNode(do_QueryInterface(aLabelNode)); - // label's value="foo" is set - if ( labelNode && NS_SUCCEEDED(labelNode->GetValue(_retval))) { - if (_retval.IsEmpty()) { - // label contains children who define it's text -- possibly HTML - nsCOMPtr content(do_QueryInterface(labelNode)); - if (content) - return AppendFlatStringFromSubtree(content, &_retval); - } - return NS_OK; - } - return NS_ERROR_FAILURE; -} /** - * 3 main cases for Xul Controls to be labeled - * 1 - control contains label="foo" - * 2 - control has, as a child, a label element - * - label has either value="foo" or children - * 3 - non-child label contains control="controlID" - * - label has either value="foo" or children - * Once a label is found, the search is discontinued, so a control - * that has a label child as well as having a label external to - * the control that uses the control="controlID" syntax will use - * the child label for its Name. + * Default Constructor */ -/* wstring getAccName (); */ -NS_IMETHODIMP nsXULFormControlAccessible::GetAccName(nsAWritableString& _retval) -{ - nsresult rv; - nsAutoString label; - - // CASE #1 -- great majority of the cases - nsCOMPtr domElement(do_QueryInterface(mDOMNode)); - NS_ASSERTION(domElement, "No domElement for accessible DOM node!"); - rv = domElement->GetAttribute(NS_LITERAL_STRING("label"), label) ; - - if (NS_FAILED(rv) || label.IsEmpty() ) { - - // CASE #2 ------ label as a child - nsCOMPtrlabelChildren; - NS_ASSERTION(domElement, "No domElement for accessible DOM node!"); - if (NS_SUCCEEDED(rv = domElement->GetElementsByTagName(NS_LITERAL_STRING("label"), getter_AddRefs(labelChildren)))) { - PRUint32 length = 0; - if (NS_SUCCEEDED(rv = labelChildren->GetLength(&length)) && length > 0) { - for (PRUint32 i = 0; i < length; ++i) { - nsCOMPtr child; - if (NS_SUCCEEDED(rv = labelChildren->Item(i, getter_AddRefs(child) ))) { - rv = AppendLabelText(child, label); - } - } - } - } - - if (NS_FAILED(rv) || label.IsEmpty()) { - - // CASE #3 ----- non-child label pointing to control - // XXX jgaunt - // decided to search the parent's children for labels linked to - // this control via the control="controlID" syntax, instead of searching - // the entire document with: - // - // nsCOMPtr doc; - // nsCOMPtr content(do_QueryInterface(mDOMNode)); - // content->GetDocument(*getter_AddRefs(doc)); - // nsCOMPtr xulDoc(do_QueryInterface(doc)); - // if (xulDoc) { - // nsCOMPtrlabelList; - // if (NS_SUCCEEDED(rv = xulDoc->GetElementsByAttribute(NS_LITERAL_STRING("control"), controlID, getter_AddRefs(labelList)))) - // - // This should keep search times down and still get the relevant - // labels. - nsCOMPtr parent; - if (NS_SUCCEEDED(rv = mDOMNode->GetParentNode(getter_AddRefs(parent)))) { - nsCOMPtr xulElement(do_QueryInterface(parent)); - NS_ASSERTION(xulElement, "No xulElement for parent DOM Node!"); - if (xulElement) { - nsAutoString controlID; - nsCOMPtrlabelList; - if (NS_SUCCEEDED(rv = xulElement->GetElementsByAttribute(NS_LITERAL_STRING("control"), controlID, getter_AddRefs(labelList)))) - { - PRUint32 length = 0; - if (NS_SUCCEEDED(rv = labelList->GetLength(&length)) && length > 0) { - for (PRUint32 i = 0; i < length; ++i) { - nsCOMPtr child; - if (NS_SUCCEEDED(rv = labelList->Item(i, getter_AddRefs(child) ))) { - rv = AppendLabelText(child, label); - } - } - } - } - } - } // End of CASE #3 - } // END of CASE #2 - } // END of CASE #1 - - label.CompressWhitespace(); - if (label.IsEmpty()) - return nsAccessible::GetAccName(_retval); - - _retval.Assign(label); - return NS_OK; -} - -/** - * XUL Form controls can be focusable, focused, unavailable, ?protected? - **/ -NS_IMETHODIMP nsXULFormControlAccessible::GetAccState(PRUint32 *_retval) -{ - // Get the focused state from the nsAccessible - nsAccessible::GetAccState(_retval); - - PRBool disabled = PR_FALSE; - nsCOMPtr xulFormElement(do_QueryInterface(mDOMNode)); - if (xulFormElement) - xulFormElement->GetDisabled(&disabled); - - if (disabled) - *_retval |= STATE_UNAVAILABLE; - else - *_retval |= STATE_FOCUSABLE; - - return NS_OK; -} - -// ----- XUL Button: can contain arbitrary HTML content ----- - nsXULButtonAccessible::nsXULButtonAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell): -nsBlockAccessible(aNode, aShell) +nsFormControlAccessible(aNode, aShell) { } -/* PRUint8 getAccNumActions (); */ +/** + * Only one actions available + */ NS_IMETHODIMP nsXULButtonAccessible::GetAccNumActions(PRUint8 *_retval) { - *_retval = 1; + *_retval = eSingle_Action; return NS_OK;; } -/* wstring getAccActionName (in PRUint8 index); */ +/** + * Return the name of our only action + */ NS_IMETHODIMP nsXULButtonAccessible::GetAccActionName(PRUint8 index, nsAWritableString& _retval) { - if (index == 0) { + if (index == eAction_Click) { _retval = NS_LITERAL_STRING("press"); return NS_OK; } return NS_ERROR_INVALID_ARG; } -/* void accDoAction (in PRUint8 index); */ +/** + * Tell the button to do it's action + */ NS_IMETHODIMP nsXULButtonAccessible::AccDoAction(PRUint8 index) { if (index == 0) { @@ -225,57 +101,62 @@ NS_IMETHODIMP nsXULButtonAccessible::AccDoAction(PRUint8 index) return NS_ERROR_INVALID_ARG; } -/* unsigned long getAccRole (); */ +/** + * We are a pushbutton + */ NS_IMETHODIMP nsXULButtonAccessible::GetAccRole(PRUint32 *_retval) { *_retval = ROLE_PUSHBUTTON; return NS_OK; } -/* long getAccState (); */ +/** + * Possible states: focused, focusable, unavailable(disabled) + */ NS_IMETHODIMP nsXULButtonAccessible::GetAccState(PRUint32 *_retval) { - nsAccessible::GetAccState(_retval); + // get focus and disable status from base class + nsFormControlAccessible::GetAccState(_retval); *_retval |= STATE_FOCUSABLE; return NS_OK; } +/** + * XUL checkbox + */ -/* wstring getAccName (); */ -NS_IMETHODIMP nsXULButtonAccessible::GetAccName(nsAWritableString& _retval) -{ - nsCOMPtr buttonElement(do_QueryInterface(mDOMNode)); - if ( buttonElement ) { - return buttonElement->GetLabel(_retval); - } - return NS_ERROR_FAILURE; -} - -// --- XUL checkbox ----- - +/** + * Default Constructor + */ nsXULCheckboxAccessible::nsXULCheckboxAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell): -nsXULFormControlAccessible(aNode, aShell) +nsFormControlAccessible(aNode, aShell) { } -/* unsigned long getAccRole (); */ +/** + * We are a CheckButton + */ NS_IMETHODIMP nsXULCheckboxAccessible::GetAccRole(PRUint32 *_retval) { *_retval = ROLE_CHECKBUTTON; return NS_OK; } -/* PRUint8 getAccNumActions (); */ +/** + * Only one action available + */ NS_IMETHODIMP nsXULCheckboxAccessible::GetAccNumActions(PRUint8 *_retval) { - *_retval = 1; + *_retval = eSingle_Action; return NS_OK; } -/* wstring getAccActionName (in PRUint8 index); */ +/** + * Return the name of our only action + */ NS_IMETHODIMP nsXULCheckboxAccessible::GetAccActionName(PRUint8 index, nsAWritableString& _retval) { - if (index == 0) { // 0 is the magic value for default action + if (index == eAction_Click) { // check or uncheck PRUint32 state; GetAccState(&state); @@ -290,10 +171,12 @@ NS_IMETHODIMP nsXULCheckboxAccessible::GetAccActionName(PRUint8 index, nsAWritab return NS_ERROR_INVALID_ARG; } -/* void accDoAction (in PRUint8 index); */ +/** + * Tell the checkbox to do its only action -- check( or uncheck) itself + */ NS_IMETHODIMP nsXULCheckboxAccessible::AccDoAction(PRUint8 index) { - if (index == 0) { // 0 is the magic value for default action + if (index == eAction_Click) { PRBool checked = PR_FALSE; nsCOMPtr xulCheckboxElement(do_QueryInterface(mDOMNode)); if (xulCheckboxElement) { @@ -306,10 +189,13 @@ NS_IMETHODIMP nsXULCheckboxAccessible::AccDoAction(PRUint8 index) return NS_ERROR_INVALID_ARG; } +/** + * Possible states: focused, focusable, unavailable(disabled), checked + */ NS_IMETHODIMP nsXULCheckboxAccessible::GetAccState(PRUint32 *_retval) { - // Get focus state from parent - nsXULFormControlAccessible::GetAccState(_retval); + // Get focus and disable status from base class + nsFormControlAccessible::GetAccState(_retval); // Determine Checked state PRBool checked = PR_FALSE; diff --git a/mozilla/accessible/src/xul/nsXULFormControlAccessible.h b/mozilla/accessible/src/xul/nsXULFormControlAccessible.h index 8e722e29ddb..6ccff403fd7 100644 --- a/mozilla/accessible/src/xul/nsXULFormControlAccessible.h +++ b/mozilla/accessible/src/xul/nsXULFormControlAccessible.h @@ -41,40 +41,22 @@ #define _nsXULFormControlAccessible_H_ // NOTE: alphabetically ordered -#include "nsAccessible.h" #include "nsBaseWidgetAccessible.h" +#include "nsFormControlAccessible.h" #include "nsHTMLFormControlAccessible.h" -#include "nsIDOMXULLabelElement.h" -/* Accessible for supporting for controls - * supports: - * - walking up to get name from label - * - support basic state - */ -class nsXULFormControlAccessible : public nsLeafAccessible -{ -public: - nsXULFormControlAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell); - NS_IMETHOD GetAccName(nsAWritableString& _retval); - NS_IMETHOD GetAccState(PRUint32 *_retval); - -protected: - NS_IMETHODIMP AppendLabelText(nsIDOMNode *aLabelNode, nsAWritableString& _retval); -}; - -class nsXULButtonAccessible : public nsBlockAccessible +class nsXULButtonAccessible : public nsFormControlAccessible { public: nsXULButtonAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell); NS_IMETHOD GetAccRole(PRUint32 *_retval); - NS_IMETHOD GetAccName(nsAWritableString& _retval); NS_IMETHOD GetAccState(PRUint32 *_retval); NS_IMETHOD GetAccNumActions(PRUint8 *_retval); NS_IMETHOD GetAccActionName(PRUint8 index, nsAWritableString& _retval); NS_IMETHOD AccDoAction(PRUint8 index); }; -class nsXULCheckboxAccessible : public nsXULFormControlAccessible +class nsXULCheckboxAccessible : public nsFormControlAccessible { public: nsXULCheckboxAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell); @@ -86,3 +68,4 @@ public: }; #endif + diff --git a/mozilla/accessible/src/xul/nsXULTextAccessible.cpp b/mozilla/accessible/src/xul/nsXULTextAccessible.cpp index 90de5609af1..72e83b2b5a9 100644 --- a/mozilla/accessible/src/xul/nsXULTextAccessible.cpp +++ b/mozilla/accessible/src/xul/nsXULTextAccessible.cpp @@ -39,7 +39,6 @@ // NOTE: alphabetically ordered #include "nsIDOMXULDescriptionElement.h" -#include "nsIDOMXULLabelElement.h" #include "nsWeakReference.h" #include "nsXULTextAccessible.h" diff --git a/mozilla/accessible/src/xul/nsXULTextAccessible.h b/mozilla/accessible/src/xul/nsXULTextAccessible.h index fad3d2f796e..235345fe562 100644 --- a/mozilla/accessible/src/xul/nsXULTextAccessible.h +++ b/mozilla/accessible/src/xul/nsXULTextAccessible.h @@ -40,8 +40,7 @@ #ifndef _nsXULTextAccessible_H_ #define _nsXULTextAccessible_H_ -#include "nsAccessible.h" -#include "nsBaseWidgetAccessible.h" +#include "nsFormControlAccessible.h" class nsIWeakReference;