Bug 570405 - nsAccEvent should deal with nsAccessible, r=davidb

This commit is contained in:
Alexander Surkov 2010-06-12 13:04:24 +09:00
parent 7eb105907c
commit ea7efbc4a9
14 changed files with 69 additions and 77 deletions

View File

@ -1108,8 +1108,7 @@ nsAccessibleWrap::HandleAccEvent(nsAccEvent *aEvent)
nsresult
nsAccessibleWrap::FirePlatformEvent(nsAccEvent *aEvent)
{
nsCOMPtr<nsIAccessible> accessible;
aEvent->GetAccessible(getter_AddRefs(accessible));
nsAccessible *accessible = aEvent->GetAccessible();
NS_ENSURE_TRUE(accessible, NS_ERROR_FAILURE);
PRUint32 type = aEvent->GetEventType();
@ -1156,7 +1155,7 @@ nsAccessibleWrap::FirePlatformEvent(nsAccEvent *aEvent)
case nsIAccessibleEvent::EVENT_VALUE_CHANGE:
{
MAI_LOG_DEBUG(("\n\nReceived: EVENT_VALUE_CHANGE\n"));
nsCOMPtr<nsIAccessibleValue> value(do_QueryInterface(accessible));
nsCOMPtr<nsIAccessibleValue> value(do_QueryObject(accessible));
if (value) { // Make sure this is a numeric value
// Don't fire for MSAA string value changes (e.g. text editing)
// ATK values are always numeric
@ -1318,7 +1317,7 @@ nsAccessibleWrap::FirePlatformEvent(nsAccEvent *aEvent)
{
MAI_LOG_DEBUG(("\n\nReceived: EVENT_WINDOW_ACTIVATED\n"));
nsRootAccessible *rootAcc =
static_cast<nsRootAccessible *>(accessible.get());
static_cast<nsRootAccessible *>(accessible);
rootAcc->mActivated = PR_TRUE;
guint id = g_signal_lookup ("activate", MAI_TYPE_ATK_OBJECT);
g_signal_emit(atkObj, id, 0);
@ -1331,7 +1330,7 @@ nsAccessibleWrap::FirePlatformEvent(nsAccEvent *aEvent)
{
MAI_LOG_DEBUG(("\n\nReceived: EVENT_WINDOW_DEACTIVATED\n"));
nsRootAccessible *rootAcc =
static_cast<nsRootAccessible *>(accessible.get());
static_cast<nsRootAccessible *>(accessible);
rootAcc->mActivated = PR_FALSE;
guint id = g_signal_lookup ("deactivate", MAI_TYPE_ATK_OBJECT);
g_signal_emit(atkObj, id, 0);

View File

@ -49,14 +49,10 @@
#include "nsIDOMDocument.h"
#include "nsIEventStateManager.h"
#include "nsIPersistentProperties2.h"
#include "nsIServiceManager.h"
#ifdef MOZ_XUL
#include "nsIDOMXULMultSelectCntrlEl.h"
#endif
#include "nsIContent.h"
#include "nsIPresShell.h"
#include "nsPresContext.h"
////////////////////////////////////////////////////////////////////////////////
// nsAccEvent
@ -65,7 +61,14 @@
////////////////////////////////////////////////////////////////////////////////
// nsAccEvent. nsISupports
NS_IMPL_CYCLE_COLLECTION_1(nsAccEvent, mAccessible)
NS_IMPL_CYCLE_COLLECTION_CLASS(nsAccEvent)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsAccEvent)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mAccessible)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsAccEvent)
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mAccessible");
cb.NoteXPCOMChild(static_cast<nsIAccessible*>(tmp->mAccessible));
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsAccEvent)
NS_INTERFACE_MAP_ENTRY(nsIAccessibleEvent)
@ -79,7 +82,7 @@ NS_IMPL_CYCLE_COLLECTING_RELEASE(nsAccEvent)
////////////////////////////////////////////////////////////////////////////////
// nsAccEvent. Constructors
nsAccEvent::nsAccEvent(PRUint32 aEventType, nsIAccessible *aAccessible,
nsAccEvent::nsAccEvent(PRUint32 aEventType, nsAccessible *aAccessible,
PRBool aIsAsync, EIsFromUserInput aIsFromUserInput,
EEventRule aEventRule) :
mEventType(aEventType), mEventRule(aEventRule), mIsAsync(aIsAsync),
@ -127,10 +130,7 @@ nsAccEvent::GetAccessible(nsIAccessible **aAccessible)
NS_ENSURE_ARG_POINTER(aAccessible);
*aAccessible = nsnull;
if (!mAccessible)
mAccessible = GetAccessibleForNode();
NS_IF_ADDREF(*aAccessible = mAccessible);
NS_IF_ADDREF(*aAccessible = GetAccessible());
return NS_OK;
}
@ -161,14 +161,20 @@ nsAccEvent::GetAccessibleDocument(nsIAccessibleDocument **aDocAccessible)
////////////////////////////////////////////////////////////////////////////////
// nsAccEvent: public methods
nsAccessible *
nsAccEvent::GetAccessible()
{
if (!mAccessible)
mAccessible = GetAccessibleForNode();
return mAccessible;
}
nsINode*
nsAccEvent::GetNode()
{
if (!mNode) {
nsRefPtr<nsAccessNode> accessNode(do_QueryObject(mAccessible));
if (accessNode)
mNode = accessNode->GetNode();
}
if (!mNode && mAccessible)
mNode = mAccessible->GetNode();
return mNode;
}
@ -270,7 +276,7 @@ nsAccEvent::CaptureIsFromUserInput(EIsFromUserInput aIsFromUserInput)
NS_IMPL_ISUPPORTS_INHERITED1(nsAccReorderEvent, nsAccEvent,
nsAccReorderEvent)
nsAccReorderEvent::nsAccReorderEvent(nsIAccessible *aAccTarget,
nsAccReorderEvent::nsAccReorderEvent(nsAccessible *aAccTarget,
PRBool aIsAsynch,
PRBool aIsUnconditional,
nsINode *aReasonNode) :
@ -307,7 +313,7 @@ NS_IMPL_ISUPPORTS_INHERITED1(nsAccStateChangeEvent, nsAccEvent,
// support correct state change coalescence (XXX Bug 569356). Also we need to
// decide how to coalesce events created via accessible (instead of node).
nsAccStateChangeEvent::
nsAccStateChangeEvent(nsIAccessible *aAccessible,
nsAccStateChangeEvent(nsAccessible *aAccessible,
PRUint32 aState, PRBool aIsExtraState,
PRBool aIsEnabled, PRBool aIsAsynch,
EIsFromUserInput aIsFromUserInput):
@ -380,7 +386,7 @@ NS_IMPL_ISUPPORTS_INHERITED1(nsAccTextChangeEvent, nsAccEvent,
// a defunct accessible so the behaviour should be equivalent.
// XXX revisit this when coalescence is faster (eCoalesceFromSameSubtree)
nsAccTextChangeEvent::
nsAccTextChangeEvent(nsIAccessible *aAccessible,
nsAccTextChangeEvent(nsAccessible *aAccessible,
PRInt32 aStart, PRUint32 aLength,
nsAString& aModifiedText, PRBool aIsInserted,
PRBool aIsAsynch, EIsFromUserInput aIsFromUserInput) :
@ -427,7 +433,7 @@ NS_IMPL_ISUPPORTS_INHERITED1(nsAccCaretMoveEvent, nsAccEvent,
nsIAccessibleCaretMoveEvent)
nsAccCaretMoveEvent::
nsAccCaretMoveEvent(nsIAccessible *aAccessible, PRInt32 aCaretOffset) :
nsAccCaretMoveEvent(nsAccessible *aAccessible, PRInt32 aCaretOffset) :
nsAccEvent(::nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED, aAccessible, PR_TRUE), // Currently always asynch
mCaretOffset(aCaretOffset)
{
@ -457,7 +463,7 @@ NS_IMPL_ISUPPORTS_INHERITED1(nsAccTableChangeEvent, nsAccEvent,
nsIAccessibleTableChangeEvent)
nsAccTableChangeEvent::
nsAccTableChangeEvent(nsIAccessible *aAccessible, PRUint32 aEventType,
nsAccTableChangeEvent(nsAccessible *aAccessible, PRUint32 aEventType,
PRInt32 aRowOrColIndex, PRInt32 aNumRowsOrCols, PRBool aIsAsynch):
nsAccEvent(aEventType, aAccessible, aIsAsynch),
mRowOrColIndex(aRowOrColIndex), mNumRowsOrCols(aNumRowsOrCols)

View File

@ -43,15 +43,8 @@
#include "nsIAccessibleEvent.h"
#include "nsCOMPtr.h"
#include "nsCOMArray.h"
#include "nsString.h"
#include "nsCycleCollectionParticipant.h"
#include "nsAccessible.h"
#include "nsINode.h"
#include "nsIDOMNode.h"
class nsAccessible;
class nsDocAccessible;
// Constants used to point whether the event is from user input.
@ -104,7 +97,7 @@ public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_ACCEVENT_IMPL_CID)
// Initialize with an nsIAccessible
nsAccEvent(PRUint32 aEventType, nsIAccessible *aAccessible,
nsAccEvent(PRUint32 aEventType, nsAccessible *aAccessible,
PRBool aIsAsynch = PR_FALSE,
EIsFromUserInput aIsFromUserInput = eAutoDetect,
EEventRule aEventRule = eRemoveDupes);
@ -124,8 +117,8 @@ public:
EEventRule GetEventRule() const { return mEventRule; }
PRBool IsAsync() const { return mIsAsync; }
PRBool IsFromUserInput() const { return mIsFromUserInput; }
nsIAccessible* GetAccessible() const { return mAccessible; }
nsAccessible *GetAccessible();
nsINode* GetNode();
nsDocAccessible* GetDocAccessible();
@ -146,7 +139,7 @@ protected:
PRUint32 mEventType;
EEventRule mEventRule;
PRPackedBool mIsAsync;
nsCOMPtr<nsIAccessible> mAccessible;
nsRefPtr<nsAccessible> mAccessible;
nsCOMPtr<nsINode> mNode;
friend class nsAccEventQueue;
@ -167,7 +160,7 @@ class nsAccReorderEvent : public nsAccEvent
{
public:
nsAccReorderEvent(nsIAccessible *aAccTarget, PRBool aIsAsynch,
nsAccReorderEvent(nsAccessible *aAccTarget, PRBool aIsAsynch,
PRBool aIsUnconditional, nsINode *aReasonNode);
NS_DECLARE_STATIC_IID_ACCESSOR(NS_ACCREORDEREVENT_IMPL_CID)
@ -196,7 +189,7 @@ class nsAccStateChangeEvent: public nsAccEvent,
public nsIAccessibleStateChangeEvent
{
public:
nsAccStateChangeEvent(nsIAccessible *aAccessible,
nsAccStateChangeEvent(nsAccessible *aAccessible,
PRUint32 aState, PRBool aIsExtraState,
PRBool aIsEnabled, PRBool aIsAsynch = PR_FALSE,
EIsFromUserInput aIsFromUserInput = eAutoDetect);
@ -219,7 +212,7 @@ class nsAccTextChangeEvent: public nsAccEvent,
public nsIAccessibleTextChangeEvent
{
public:
nsAccTextChangeEvent(nsIAccessible *aAccessible, PRInt32 aStart,
nsAccTextChangeEvent(nsAccessible *aAccessible, PRInt32 aStart,
PRUint32 aLength, nsAString& aModifiedText,
PRBool aIsInserted, PRBool aIsAsynch = PR_FALSE,
EIsFromUserInput aIsFromUserInput = eAutoDetect);
@ -238,7 +231,7 @@ class nsAccCaretMoveEvent: public nsAccEvent,
public nsIAccessibleCaretMoveEvent
{
public:
nsAccCaretMoveEvent(nsIAccessible *aAccessible, PRInt32 aCaretOffset);
nsAccCaretMoveEvent(nsAccessible *aAccessible, PRInt32 aCaretOffset);
nsAccCaretMoveEvent(nsINode *aNode);
NS_DECL_ISUPPORTS_INHERITED
@ -251,7 +244,7 @@ private:
class nsAccTableChangeEvent : public nsAccEvent,
public nsIAccessibleTableChangeEvent {
public:
nsAccTableChangeEvent(nsIAccessible *aAccessible, PRUint32 aEventType,
nsAccTableChangeEvent(nsAccessible *aAccessible, PRUint32 aEventType,
PRInt32 aRowOrColIndex, PRInt32 aNumRowsOrCols,
PRBool aIsAsynch);

View File

@ -527,7 +527,7 @@ nsAccUtils::IsARIASelected(nsIAccessible *aAccessible)
return PR_FALSE;
}
already_AddRefed<nsIAccessibleText>
already_AddRefed<nsHyperTextAccessible>
nsAccUtils::GetTextAccessibleFromSelection(nsISelection *aSelection,
nsINode **aNode)
{
@ -554,7 +554,7 @@ nsAccUtils::GetTextAccessibleFromSelection(nsISelection *aSelection,
if (!resultNode->IsNodeOfType(nsINode::eTEXT)) {
nsAccessible *accessible = GetAccService()->GetAccessible(resultNode);
if (accessible) {
nsIAccessibleText *textAcc = nsnull;
nsHyperTextAccessible *textAcc = nsnull;
CallQueryInterface(accessible, &textAcc);
if (textAcc) {
if (aNode)

View File

@ -59,6 +59,7 @@
class nsAccessNode;
class nsAccessible;
class nsHyperTextAccessible;
class nsHTMLTableAccessible;
class nsDocAccessible;
#ifdef MOZ_XUL
@ -238,7 +239,7 @@ public:
* @param aNode [out, optional] the DOM node of text accessible
* @return text accessible
*/
static already_AddRefed<nsIAccessibleText>
static already_AddRefed<nsHyperTextAccessible>
GetTextAccessibleFromSelection(nsISelection *aSelection,
nsINode **aNode = nsnull);

View File

@ -181,7 +181,8 @@ nsresult
nsAccessibilityService::FireAccessibleEvent(PRUint32 aEvent,
nsIAccessible *aTarget)
{
nsEventShell::FireEvent(aEvent, aTarget);
nsRefPtr<nsAccessible> accessible(do_QueryObject(aTarget));
nsEventShell::FireEvent(aEvent, accessible);
return NS_OK;
}

View File

@ -246,7 +246,7 @@ nsCaretAccessible::NormalSelectionChanged(nsIDOMDocument *aDoc,
}
nsCOMPtr<nsINode> textNode;
nsCOMPtr<nsIAccessibleText> textAcc =
nsRefPtr<nsHyperTextAccessible> textAcc =
nsAccUtils::GetTextAccessibleFromSelection(aSel, getter_AddRefs(textNode));
NS_ENSURE_STATE(textAcc);
@ -281,15 +281,13 @@ nsCaretAccessible::SpellcheckSelectionChanged(nsIDOMDocument *aDoc,
// misspelled word). If spellchecking is disabled (for example,
// @spellcheck="false" on html:body) then we won't fire any event.
nsCOMPtr<nsIAccessibleText> textAcc =
nsRefPtr<nsHyperTextAccessible> textAcc =
nsAccUtils::GetTextAccessibleFromSelection(aSel);
NS_ENSURE_STATE(textAcc);
nsCOMPtr<nsIAccessible> acc(do_QueryInterface(textAcc));
nsRefPtr<nsAccEvent> event =
new nsAccEvent(nsIAccessibleEvent::EVENT_TEXT_ATTRIBUTE_CHANGED,
acc, nsnull);
textAcc, nsnull);
nsEventShell::FireEvent(event);
return NS_OK;

View File

@ -1133,8 +1133,7 @@ nsDocAccessible::ARIAAttributeChanged(nsIContent* aContent, nsIAtom* aAttribute)
// otherwise we would need access to the old attribute value in this listener.
// This is because we don't know if the previous value of aria-checked or aria-pressed was "mixed"
// without caching that info.
nsCOMPtr<nsIAccessible> accessible;
event->GetAccessible(getter_AddRefs(accessible));
nsAccessible *accessible = event->GetAccessible();
if (accessible) {
PRBool wasMixed = (gLastFocusedAccessiblesState & nsIAccessibleStates::STATE_MIXED) != 0;
PRBool isMixed =
@ -1296,14 +1295,14 @@ nsDocAccessible::HandleAccEvent(nsAccEvent *aAccEvent)
// Protected members
void
nsDocAccessible::FireValueChangeForTextFields(nsIAccessible *aPossibleTextFieldAccessible)
nsDocAccessible::FireValueChangeForTextFields(nsAccessible *aAccessible)
{
if (nsAccUtils::Role(aPossibleTextFieldAccessible) != nsIAccessibleRole::ROLE_ENTRY)
if (nsAccUtils::Role(aAccessible) != nsIAccessibleRole::ROLE_ENTRY)
return;
// Dependent value change event for text changes in textfields
nsRefPtr<nsAccEvent> valueChangeEvent =
new nsAccEvent(nsIAccessibleEvent::EVENT_VALUE_CHANGE, aPossibleTextFieldAccessible,
new nsAccEvent(nsIAccessibleEvent::EVENT_VALUE_CHANGE, aAccessible,
PR_FALSE, eAutoDetect, nsAccEvent::eRemoveDupes);
FireDelayedAccessibleEvent(valueChangeEvent);
}
@ -1476,10 +1475,7 @@ nsDocAccessible::FireDelayedAccessibleEvent(nsAccEvent *aEvent)
void
nsDocAccessible::ProcessPendingEvent(nsAccEvent *aEvent)
{
nsCOMPtr<nsIAccessible> acc;
aEvent->GetAccessible(getter_AddRefs(acc));
nsRefPtr<nsAccessible> accessible(do_QueryObject(acc));
nsAccessible *accessible = aEvent->GetAccessible();
nsINode *node = aEvent->GetNode();
PRUint32 eventType = aEvent->GetEventType();

View File

@ -311,10 +311,11 @@ protected:
PRBool aIsAsyncChange,
EIsFromUserInput aIsFromUserInput = eAutoDetect);
/**
* If the given accessible object is a ROLE_ENTRY, fire a value change event for it
*/
void FireValueChangeForTextFields(nsIAccessible *aPossibleTextFieldAccessible);
/**
* Fire a value change event for the the given accessible if it is a text
* field (has a ROLE_ENTRY).
*/
void FireValueChangeForTextFields(nsAccessible *aAccessible);
nsAccessNodeHashtable mAccessNodeCache;
void *mWnd;

View File

@ -52,8 +52,8 @@ nsEventShell::FireEvent(nsAccEvent *aEvent)
if (!aEvent)
return;
nsRefPtr<nsAccessible> acc = do_QueryObject(aEvent->GetAccessible());
NS_ENSURE_TRUE(acc,);
nsAccessible *accessible = aEvent->GetAccessible();
NS_ENSURE_TRUE(accessible,);
nsINode* node = aEvent->GetNode();
if (node) {
@ -61,13 +61,13 @@ nsEventShell::FireEvent(nsAccEvent *aEvent)
sEventFromUserInput = aEvent->IsFromUserInput();
}
acc->HandleAccEvent(aEvent);
accessible->HandleAccEvent(aEvent);
sEventTargetNode = nsnull;
}
void
nsEventShell::FireEvent(PRUint32 aEventType, nsIAccessible *aAccessible,
nsEventShell::FireEvent(PRUint32 aEventType, nsAccessible *aAccessible,
PRBool aIsAsynch, EIsFromUserInput aIsFromUserInput)
{
NS_ENSURE_TRUE(aAccessible,);

View File

@ -67,7 +67,7 @@ public:
* @param aIsAsync [in, optional] specifies whether the origin change
* this event is fired owing to is async.
*/
static void FireEvent(PRUint32 aEventType, nsIAccessible *aAccessible,
static void FireEvent(PRUint32 aEventType, nsAccessible *aAccessible,
PRBool aIsAsynch = PR_FALSE,
EIsFromUserInput aIsFromUserInput = eAutoDetect);

View File

@ -184,8 +184,7 @@ nsAccessibleWrap::FirePlatformEvent(nsAccEvent *aEvent)
eventType != nsIAccessibleEvent::EVENT_VALUE_CHANGE)
return NS_OK;
nsCOMPtr<nsIAccessible> accessible;
aEvent->GetAccessible(getter_AddRefs(accessible));
nsAccessible *accessible = aEvent->GetAccessible();
NS_ENSURE_STATE(accessible);
mozAccessible *nativeAcc = nil;

View File

@ -1666,8 +1666,7 @@ nsAccessibleWrap::FirePlatformEvent(nsAccEvent *aEvent)
// Means we're not active.
NS_ENSURE_TRUE(mWeakShell, NS_ERROR_FAILURE);
nsCOMPtr<nsIAccessible> accessible;
aEvent->GetAccessible(getter_AddRefs(accessible));
nsAccessible *accessible = aEvent->GetAccessible();
if (!accessible)
return NS_OK;
@ -1681,11 +1680,11 @@ nsAccessibleWrap::FirePlatformEvent(nsAccEvent *aEvent)
return NS_OK; // Can't fire an event without a child ID
// See if we're in a scrollable area with its own window
nsCOMPtr<nsIAccessible> newAccessible;
nsAccessible *newAccessible = nsnull;
if (eventType == nsIAccessibleEvent::EVENT_HIDE) {
// Don't use frame from current accessible when we're hiding that
// accessible.
accessible->GetParent(getter_AddRefs(newAccessible));
newAccessible = accessible->GetParent();
} else {
newAccessible = accessible;
}

View File

@ -57,10 +57,9 @@ nsHyperTextAccessibleWrap::HandleAccEvent(nsAccEvent *aEvent)
if (eventType == nsIAccessibleEvent::EVENT_TEXT_REMOVED ||
eventType == nsIAccessibleEvent::EVENT_TEXT_INSERTED) {
nsCOMPtr<nsIAccessible> accessible;
aEvent->GetAccessible(getter_AddRefs(accessible));
nsAccessible *accessible = aEvent->GetAccessible();
if (accessible) {
nsCOMPtr<nsIWinAccessNode> winAccessNode(do_QueryInterface(accessible));
nsCOMPtr<nsIWinAccessNode> winAccessNode(do_QueryObject(accessible));
if (winAccessNode) {
void *instancePtr = NULL;
nsresult rv = winAccessNode->QueryNativeInterface(IID_IAccessibleText,