Bug 208922. Make nsIAccessNode useful for inprocess accessibility clients. r=kyle, sr=alecf

This commit is contained in:
aaronl%netscape.com 2003-06-19 18:12:52 +00:00
parent 87a3a21aa0
commit 3014b137da
12 changed files with 218 additions and 25 deletions

View File

@ -47,6 +47,7 @@ XPIDLSRCS = \
nsIAccessibleProvider.idl \
nsIAccessibleSelectable.idl \
nsIAccessNode.idl \
nsPIAccessNode.idl \
nsIAccessibleEvent.idl \
$(NULL)

View File

@ -37,13 +37,28 @@
* ***** END LICENSE BLOCK ***** */
#include "nsISupports.idl"
#include "nsIAccessibleDocument.idl"
interface nsIDOMNode;
interface nsIAccessibleDocument;
[scriptable, uuid(46820F9B-3088-4046-AB0F-56FDACDC7A82)]
interface nsIAccessNode : nsISupports
{
[noscript] void init();
[noscript] void shutdown();
readonly attribute nsIDOMNode DOMNode;
readonly attribute long numChildren;
nsIAccessNode getChildAt(in long childNum);
readonly attribute nsIAccessNode parent;
readonly attribute nsIAccessNode firstChild;
readonly attribute nsIAccessNode lastChild;
readonly attribute nsIAccessNode previousSibling;
readonly attribute nsIAccessNode nextSibling;
readonly attribute nsIAccessibleDocument accessibleDocument;
readonly attribute DOMString innerHTML;
[noscript] readonly attribute voidPtr ownerWindow;
[noscript] readonly attribute voidPtr uniqueID;
DOMString getComputedStyleValue(in DOMString pseudoElt, in DOMString propertyName);
};

View File

@ -41,7 +41,14 @@
#include "nsAccessibilityAtoms.h"
#include "nsHashtable.h"
#include "nsIAccessibilityService.h"
#include "nsIAccessibleDocument.h"
#include "nsIDocument.h"
#include "nsIDOMCSSStyleDeclaration.h"
#include "nsIDOMElement.h"
#include "nsIDOMNSHTMLElement.h"
#include "nsIDOMViewCSS.h"
#include "nsIDOMWindow.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsIFrame.h"
#include "nsIPref.h"
#include "nsIPresContext.h"
@ -71,13 +78,7 @@ nsInterfaceHashtable<nsVoidHashKey, nsIAccessNode> *nsAccessNode::gGlobalDocAcce
//-----------------------------------------------------
// construction
//-----------------------------------------------------
NS_INTERFACE_MAP_BEGIN(nsAccessNode)
NS_INTERFACE_MAP_ENTRY(nsIAccessNode)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
NS_IMPL_ADDREF(nsAccessNode)
NS_IMPL_RELEASE(nsAccessNode)
NS_IMPL_ISUPPORTS2(nsAccessNode, nsIAccessNode, nsPIAccessNode)
nsAccessNode::nsAccessNode(nsIDOMNode *aNode, nsIWeakReference* aShell):
mDOMNode(aNode), mWeakShell(aShell), mRefCnt(0),
@ -260,6 +261,165 @@ nsIFrame* nsAccessNode::GetFrame()
return frame;
}
NS_IMETHODIMP
nsAccessNode::GetDOMNode(nsIDOMNode **aNode)
{
NS_IF_ADDREF(*aNode = mDOMNode);
return NS_OK;
}
NS_IMETHODIMP
nsAccessNode::GetNumChildren(PRInt32 *aNumChildren)
{
nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
return content? content->ChildCount(*aNumChildren) : NS_ERROR_NULL_POINTER;
}
NS_IMETHODIMP
nsAccessNode::GetAccessibleDocument(nsIAccessibleDocument **aDocAccessible)
{
GetDocAccessibleFor(mWeakShell, aDocAccessible);
return NS_OK;
}
NS_IMETHODIMP
nsAccessNode::GetInnerHTML(nsAString& aInnerHTML)
{
aInnerHTML.Truncate();
nsCOMPtr<nsIDOMNSHTMLElement> domNSElement(do_QueryInterface(mDOMNode));
NS_ENSURE_TRUE(domNSElement, NS_ERROR_NULL_POINTER);
return domNSElement->GetInnerHTML(aInnerHTML);
}
nsresult
nsAccessNode::MakeAccessNode(nsIDOMNode *aNode, nsIAccessNode **aAccessNode)
{
nsCOMPtr<nsIAccessibilityService> accService =
do_GetService("@mozilla.org/accessibilityService;1");
NS_ENSURE_TRUE(accService, NS_ERROR_FAILURE);
nsCOMPtr<nsIAccessNode> accessNode;
accService->GetCachedAccessNode(aNode, mWeakShell, getter_AddRefs(accessNode));
if (!accessNode) {
nsCOMPtr<nsIAccessible> accessible;
accService->GetAccessibleInWeakShell(aNode, mWeakShell,
getter_AddRefs(accessible));
accessNode = do_QueryInterface(accessible);
}
if (accessNode) {
NS_ADDREF(*aAccessNode = accessNode);
return NS_OK;
}
nsAccessNode *newAccessNode = new nsAccessNode(aNode, mWeakShell);
if (!newAccessNode) {
return NS_ERROR_OUT_OF_MEMORY;
}
NS_ADDREF(*aAccessNode = newAccessNode);
newAccessNode->Init();
return NS_OK;
}
NS_IMETHODIMP
nsAccessNode::GetFirstChild(nsIAccessNode **aAccessNode)
{
NS_ENSURE_TRUE(mDOMNode, NS_ERROR_NULL_POINTER);
nsCOMPtr<nsIDOMNode> domNode;
mDOMNode->GetFirstChild(getter_AddRefs(domNode));
NS_ENSURE_TRUE(domNode, NS_ERROR_NULL_POINTER);
return MakeAccessNode(domNode, aAccessNode);
}
NS_IMETHODIMP
nsAccessNode::GetLastChild(nsIAccessNode **aAccessNode)
{
NS_ENSURE_TRUE(mDOMNode, NS_ERROR_NULL_POINTER);
nsCOMPtr<nsIDOMNode> domNode;
mDOMNode->GetLastChild(getter_AddRefs(domNode));
NS_ENSURE_TRUE(domNode, NS_ERROR_NULL_POINTER);
return MakeAccessNode(domNode, aAccessNode);
}
NS_IMETHODIMP
nsAccessNode::GetParent(nsIAccessNode **aAccessNode)
{
NS_ENSURE_TRUE(mDOMNode, NS_ERROR_NULL_POINTER);
nsCOMPtr<nsIDOMNode> domNode;
mDOMNode->GetParentNode(getter_AddRefs(domNode));
NS_ENSURE_TRUE(domNode, NS_ERROR_NULL_POINTER);
return MakeAccessNode(domNode, aAccessNode);
}
NS_IMETHODIMP
nsAccessNode::GetPreviousSibling(nsIAccessNode **aAccessNode)
{
NS_ENSURE_TRUE(mDOMNode, NS_ERROR_NULL_POINTER);
nsCOMPtr<nsIDOMNode> domNode;
mDOMNode->GetPreviousSibling(getter_AddRefs(domNode));
NS_ENSURE_TRUE(domNode, NS_ERROR_NULL_POINTER);
return MakeAccessNode(domNode, aAccessNode);
}
NS_IMETHODIMP
nsAccessNode::GetNextSibling(nsIAccessNode **aAccessNode)
{
NS_ENSURE_TRUE(mDOMNode, NS_ERROR_NULL_POINTER);
nsCOMPtr<nsIDOMNode> domNode;
mDOMNode->GetNextSibling(getter_AddRefs(domNode));
NS_ENSURE_TRUE(domNode, NS_ERROR_NULL_POINTER);
return MakeAccessNode(domNode, aAccessNode);
}
NS_IMETHODIMP
nsAccessNode::GetChildAt(PRInt32 aChildNum, nsIAccessNode **aAccessNode)
{
nsCOMPtr<nsIContent> child, content(do_QueryInterface(mDOMNode));
NS_ENSURE_TRUE(content, NS_ERROR_NULL_POINTER);
content->ChildAt(aChildNum, getter_AddRefs(child));
nsCOMPtr<nsIDOMNode> domNode(do_QueryInterface(child));
NS_ENSURE_TRUE(domNode, NS_ERROR_NULL_POINTER);
return MakeAccessNode(domNode, aAccessNode);
}
NS_IMETHODIMP
nsAccessNode::GetComputedStyleValue(const nsAString& aPseudoElt, const nsAString& aPropertyName, nsAString& aValue)
{
nsCOMPtr<nsIDOMElement> domElement(do_QueryInterface(mDOMNode));
nsCOMPtr<nsIPresContext> presContext(GetPresContext());
NS_ENSURE_TRUE(domElement && presContext, NS_ERROR_FAILURE);
nsCOMPtr<nsISupports> container;
presContext->GetContainer(getter_AddRefs(container));
nsCOMPtr<nsIDOMWindow> domWin(do_GetInterface(container));
nsCOMPtr<nsIDOMViewCSS> viewCSS(do_QueryInterface(domWin));
NS_ENSURE_TRUE(viewCSS, NS_ERROR_FAILURE);
nsCOMPtr<nsIDOMCSSStyleDeclaration> styleDecl;
viewCSS->GetComputedStyle(domElement, aPseudoElt, getter_AddRefs(styleDecl));
NS_ENSURE_TRUE(styleDecl, NS_ERROR_FAILURE);
return styleDecl->GetPropertyValue(aPropertyName, aValue);
}
/***************** Hashtable of nsIAccessNode's *****************/
void nsAccessNode::GetDocAccessibleFor(nsIWeakReference *aPresShell,
@ -296,7 +456,8 @@ void nsAccessNode::GetCacheEntry(nsInterfaceHashtable<nsVoidHashKey, nsIAccessNo
PLDHashOperator nsAccessNode::ClearCacheEntry(const void* aKey, nsCOMPtr<nsIAccessNode>& aAccessNode, void* aUserArg)
{
aAccessNode->Shutdown();
nsCOMPtr<nsPIAccessNode> privateAccessNode(do_QueryInterface(aAccessNode));
privateAccessNode->Shutdown();
return PL_DHASH_REMOVE;
}

View File

@ -45,6 +45,7 @@
#include "nsCOMPtr.h"
#include "nsIAccessNode.h"
#include "nsPIAccessNode.h"
#include "nsIDOMNode.h"
#include "nsIStringBundle.h"
#include "nsWeakReference.h"
@ -89,7 +90,7 @@ private:
const void* mValue;
};
class nsAccessNode: public nsIAccessNode
class nsAccessNode: public nsIAccessNode, public nsPIAccessNode
{
public: // construction, destruction
nsAccessNode(nsIDOMNode *, nsIWeakReference* aShell);
@ -99,6 +100,7 @@ class nsAccessNode: public nsIAccessNode
NS_IMETHOD_(nsrefcnt) AddRef(void);
NS_IMETHOD_(nsrefcnt) Release(void);
NS_DECL_NSIACCESSNODE
NS_DECL_NSPIACCESSNODE
static void InitXPAccessibility();
static void ShutdownXPAccessibility();
@ -117,6 +119,7 @@ class nsAccessNode: public nsIAccessNode
nsIAccessibleDocument **aDocAccessible);
protected:
nsresult MakeAccessNode(nsIDOMNode *aNode, nsIAccessNode **aAccessNode);
already_AddRefed<nsIPresShell> GetPresShell();
already_AddRefed<nsIPresContext> GetPresContext();
already_AddRefed<nsIAccessibleDocument> GetDocAccessible();

View File

@ -74,6 +74,7 @@
#include "nsOuterDocAccessible.h"
#include "nsRootAccessibleWrap.h"
#include "nsTextFragment.h"
#include "nsPIAccessNode.h"
#ifdef MOZ_XUL
#include "nsXULColorPickerAccessible.h"
@ -111,6 +112,7 @@ nsAccessibilityService::nsAccessibilityService()
return;
observerService->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, PR_FALSE);
observerService->AddObserver(this, NS_PRESSHELL_DESTROY_TOPIC, PR_FALSE);
nsAccessNodeWrap::InitAccessibility();
}
@ -132,9 +134,20 @@ nsAccessibilityService::Observe(nsISupports *aSubject, const char *aTopic,
do_GetService("@mozilla.org/observer-service;1");
if (observerService) {
observerService->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID);
observerService->RemoveObserver(this, NS_PRESSHELL_DESTROY_TOPIC);
}
nsAccessNodeWrap::ShutdownAccessibility();
}
else if (!nsCRT::strcmp(aTopic, NS_PRESSHELL_DESTROY_TOPIC)) {
nsCOMPtr<nsIWeakReference> weakShell(do_GetWeakReference(aSubject));
if (weakShell) {
nsCOMPtr<nsIAccessibleDocument> accessibleDoc;
nsAccessNode::GetDocAccessibleFor(weakShell, getter_AddRefs(accessibleDoc));
if (accessibleDoc) {
accessibleDoc->Destroy();
}
}
}
return NS_OK;
}
@ -251,8 +264,8 @@ nsAccessibilityService::CreateRootAccessible(nsIPresShell *aShell,
NS_ASSERTION(eventReceiver, "Doc accessible does not receive events");
eventReceiver->AddEventListeners();
nsCOMPtr<nsIAccessNode> accessNode(do_QueryInterface(*aRootAcc));
accessNode->Init();
nsCOMPtr<nsPIAccessNode> privateAccessNode(do_QueryInterface(*aRootAcc));
privateAccessNode->Init();
NS_ADDREF(*aRootAcc);
@ -1534,8 +1547,8 @@ nsresult nsAccessibilityService::GetAccessible(nsIDOMNode *aNode,
if (state & (nsIAccessible::STATE_INVISIBLE | nsIAccessible::STATE_OFFSCREEN))
return NS_ERROR_FAILURE;
}
accessNode = do_QueryInterface(newAcc);
accessNode->Init(); // Add to cache, etc.
nsCOMPtr<nsPIAccessNode> privateAccessNode = do_QueryInterface(newAcc);
privateAccessNode->Init(); // Add to cache, etc.
*aAccessible = newAcc;
NS_ADDREF(*aAccessible);
return NS_OK;
@ -1627,8 +1640,8 @@ nsresult nsAccessibilityService::GetAccessible(nsIDOMNode *aNode,
if (!newAcc)
return NS_ERROR_FAILURE;
accessNode = do_QueryInterface(newAcc);
accessNode->Init(); // Add to cache, etc.
nsCOMPtr<nsPIAccessNode> privateAccessNode = do_QueryInterface(newAcc);
privateAccessNode->Init(); // Add to cache, etc.
*aAccessible = newAcc;
NS_ADDREF(*aAccessible);

View File

@ -39,6 +39,7 @@
* ***** END LICENSE BLOCK ***** */
#include "nsAccessible.h"
#include "nsIAccessibleDocument.h"
#include "nsIDocument.h"
#include "nsIImageDocument.h"
#include "nsIPresShell.h"

View File

@ -39,6 +39,7 @@
#include "nsBaseWidgetAccessible.h"
#include "nsIAccessibilityService.h"
#include "nsIAccessibleDocument.h"
#include "nsAccessibleWrap.h"
#include "nsGUIEvent.h"
#include "nsILink.h"

View File

@ -915,7 +915,8 @@ NS_IMETHODIMP nsDocAccessible::InvalidateCacheSubtree(nsIDOMNode *aStartNode)
if (accessNode != NS_STATIC_CAST(nsIAccessNode*, this)) {
void *uniqueID;
accessNode->GetUniqueID(&uniqueID);
accessNode->Shutdown();
nsCOMPtr<nsPIAccessNode> privateAccessNode(do_QueryInterface(accessNode));
privateAccessNode->Shutdown();
// Remove from hash table as well
mAccessNodeCache->Remove(uniqueID);
}

View File

@ -38,6 +38,7 @@
#include "nsOuterDocAccessible.h"
#include "nsIAccessibilityService.h"
#include "nsIAccessibleDocument.h"
#include "nsIDocument.h"
#include "nsIPresShell.h"
#include "nsIServiceManager.h"

View File

@ -39,6 +39,7 @@
* ***** END LICENSE BLOCK ***** */
#include "nsHTMLTextAccessible.h"
#include "nsIAccessibleDocument.h"
#include "nsIFrame.h"
#include "nsIPresContext.h"
#include "nsIPresShell.h"

View File

@ -190,12 +190,6 @@ NS_IMETHODIMP nsDocAccessibleWrap::FireToolkitEvent(PRUint32 aEvent, nsIAccessib
// Clear out the cache in this subtree
}
if (role == EVENT_OBJECT_REORDER) {
// Probably need to do this somewhere else so simple dom nodes get shutdown
nsCOMPtr<nsIAccessNode> accessNode(do_QueryInterface(aAccessible));
accessNode->Shutdown();
}
HWND hWnd = NS_REINTERPRET_CAST(HWND, mWnd);
if (gmGetGUIThreadInfo && (aEvent == EVENT_FOCUS ||
aEvent == EVENT_MENUPOPUPSTART ||

View File

@ -41,6 +41,7 @@
#include "nsTextAccessibleWrap.h"
#include "ISimpleDOMText_i.c"
#include "nsContentCID.h"
#include "nsIAccessibleDocument.h"
#include "nsIDOMRange.h"
#include "nsIFrame.h"
#include "nsIPresContext.h"