Bug 570405 - nsAccEvent should deal with nsAccessible, r=davidb
authorAlexander Surkov <surkov.alexander@gmail.com>
Sat, 12 Jun 2010 13:04:24 +0900
changeset 43537 28a9850ae772dce475fd81c6c9436ad569a2b2f7
parent 43536 1d840cf822e6f12f926c6e714beb8d45a4a19c95
child 43538 6768f98d8cea22e04a15be22c62509c872c2dba9
push id13758
push usersurkov.alexander@gmail.com
push dateSat, 12 Jun 2010 04:05:45 +0000
treeherdermozilla-central@85a2ebbd0ddf [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdavidb
bugs570405
milestone1.9.3a6pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 570405 - nsAccEvent should deal with nsAccessible, r=davidb
accessible/src/atk/nsAccessibleWrap.cpp
accessible/src/base/nsAccEvent.cpp
accessible/src/base/nsAccEvent.h
accessible/src/base/nsAccUtils.cpp
accessible/src/base/nsAccUtils.h
accessible/src/base/nsAccessibilityService.cpp
accessible/src/base/nsCaretAccessible.cpp
accessible/src/base/nsDocAccessible.cpp
accessible/src/base/nsDocAccessible.h
accessible/src/base/nsEventShell.cpp
accessible/src/base/nsEventShell.h
accessible/src/mac/nsAccessibleWrap.mm
accessible/src/msaa/nsAccessibleWrap.cpp
accessible/src/msaa/nsHyperTextAccessibleWrap.cpp
--- a/accessible/src/atk/nsAccessibleWrap.cpp
+++ b/accessible/src/atk/nsAccessibleWrap.cpp
@@ -1103,18 +1103,17 @@ nsAccessibleWrap::HandleAccEvent(nsAccEv
     NS_ENSURE_SUCCESS(rv, rv);
 
     return FirePlatformEvent(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();
 
     AtkObject *atkObj = nsAccessibleWrap::GetAtkObject(accessible);
 
     // We don't create ATK objects for nsIAccessible plain text leaves,
     // just return NS_OK in such case
@@ -1151,17 +1150,17 @@ nsAccessibleWrap::FirePlatformEvent(nsAc
                                         PR_FALSE, PR_TRUE);
             return FireAtkStateChangeEvent(stateChangeEvent, atkObj);
         }
       } break;
 
     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
             g_object_notify( (GObject*)atkObj, "accessible-value" );
         }
       } break;
 
     case nsIAccessibleEvent::EVENT_SELECTION_CHANGED:
@@ -1313,30 +1312,30 @@ nsAccessibleWrap::FirePlatformEvent(nsAc
     case nsIAccessibleEvent::EVENT_MENU_END:
         MAI_LOG_DEBUG(("\n\nReceived: EVENT_MENU_END\n"));
         break;
 
     case nsIAccessibleEvent::EVENT_WINDOW_ACTIVATE:
       {
         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);
 
         // Always fire a current focus event after activation.
         rootAcc->FireCurrentFocusEvent();
       } break;
 
     case nsIAccessibleEvent::EVENT_WINDOW_DEACTIVATE:
       {
         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);
       } break;
 
     case nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE:
       {
         MAI_LOG_DEBUG(("\n\nReceived: EVENT_DOCUMENT_LOAD_COMPLETE\n"));
--- a/accessible/src/base/nsAccEvent.cpp
+++ b/accessible/src/base/nsAccEvent.cpp
@@ -44,47 +44,50 @@
 #include "nsDocAccessible.h"
 #include "nsIAccessibleText.h"
 #ifdef MOZ_XUL
 #include "nsXULTreeAccessible.h"
 #endif
 
 #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
 ////////////////////////////////////////////////////////////////////////////////
 
 ////////////////////////////////////////////////////////////////////////////////
 // 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)
   NS_INTERFACE_MAP_ENTRY(nsAccEvent)
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsAccEvent)
 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),
   mAccessible(aAccessible)
 {
   CaptureIsFromUserInput(aIsFromUserInput);
 }
 
@@ -122,20 +125,17 @@ nsAccEvent::GetEventType(PRUint32 *aEven
 }
 
 NS_IMETHODIMP
 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;
 }
 
 NS_IMETHODIMP
 nsAccEvent::GetDOMNode(nsIDOMNode **aDOMNode)
 {
   NS_ENSURE_ARG_POINTER(aDOMNode);
   *aDOMNode = nsnull;
@@ -156,24 +156,30 @@ nsAccEvent::GetAccessibleDocument(nsIAcc
 
   NS_IF_ADDREF(*aDocAccessible = GetDocAccessible());
   return NS_OK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // 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;
 }
 
 nsDocAccessible*
 nsAccEvent::GetDocAccessible()
 {
   nsINode *node = GetNode();
@@ -265,17 +271,17 @@ nsAccEvent::CaptureIsFromUserInput(EIsFr
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccReorderEvent
 ////////////////////////////////////////////////////////////////////////////////
 
 NS_IMPL_ISUPPORTS_INHERITED1(nsAccReorderEvent, nsAccEvent,
                              nsAccReorderEvent)
 
-nsAccReorderEvent::nsAccReorderEvent(nsIAccessible *aAccTarget,
+nsAccReorderEvent::nsAccReorderEvent(nsAccessible *aAccTarget,
                                      PRBool aIsAsynch,
                                      PRBool aIsUnconditional,
                                      nsINode *aReasonNode) :
   nsAccEvent(::nsIAccessibleEvent::EVENT_REORDER, aAccTarget,
              aIsAsynch, eAutoDetect, nsAccEvent::eCoalesceFromSameSubtree),
   mUnconditionalEvent(aIsUnconditional), mReasonNode(aReasonNode)
 {
 }
@@ -302,17 +308,17 @@ nsAccReorderEvent::HasAccessibleInReason
 
 NS_IMPL_ISUPPORTS_INHERITED1(nsAccStateChangeEvent, nsAccEvent,
                              nsIAccessibleStateChangeEvent)
 
 // Note: we pass in eAllowDupes to the base class because we don't currently
 // 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):
   nsAccEvent(nsIAccessibleEvent::EVENT_STATE_CHANGE, aAccessible, aIsAsynch,
              aIsFromUserInput, eAllowDupes),
   mState(aState), mIsExtraState(aIsExtraState), mIsEnabled(aIsEnabled)
 {
 }
@@ -375,17 +381,17 @@ NS_IMPL_ISUPPORTS_INHERITED1(nsAccTextCh
 // events coalescence. We fire delayed text change events in nsDocAccessible but
 // we continue to base the event off the accessible object rather than just the
 // node. This means we won't try to create an accessible based on the node when
 // we are ready to fire the event and so we will no longer assert at that point
 // if the node was removed from the document. Either way, the AT won't work with
 // 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) :
   nsAccEvent(aIsInserted ? nsIAccessibleEvent::EVENT_TEXT_INSERTED : nsIAccessibleEvent::EVENT_TEXT_REMOVED,
              aAccessible, aIsAsynch, aIsFromUserInput, eAllowDupes),
   mStart(aStart), mLength(aLength), mIsInserted(aIsInserted),
   mModifiedText(aModifiedText)
 {
@@ -422,17 +428,17 @@ nsAccTextChangeEvent::GetModifiedText(ns
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccCaretMoveEvent
 ////////////////////////////////////////////////////////////////////////////////
 
 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)
 {
 }
 
 nsAccCaretMoveEvent::
   nsAccCaretMoveEvent(nsINode *aNode) :
   nsAccEvent(::nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED, aNode, PR_TRUE), // Currently always asynch
@@ -452,17 +458,17 @@ nsAccCaretMoveEvent::GetCaretOffset(PRIn
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccTableChangeEvent
 ////////////////////////////////////////////////////////////////////////////////
 
 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)
 {
 }
 
 NS_IMETHODIMP
 nsAccTableChangeEvent::GetRowOrColIndex(PRInt32* aRowOrColIndex)
--- a/accessible/src/base/nsAccEvent.h
+++ b/accessible/src/base/nsAccEvent.h
@@ -38,25 +38,18 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef _nsAccEvent_H_
 #define _nsAccEvent_H_
 
 #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.
 enum EIsFromUserInput
 {
   // eNoUserInput: event is not from user input
   eNoUserInput = 0,
   // eFromUserInput: event is from user input
@@ -99,17 +92,17 @@ public:
 
      // eDoNotEmit : This event is confirmed as a duplicate, do not emit it.
      eDoNotEmit
   };
 
   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);
   // Initialize with an nsIDOMNode
   nsAccEvent(PRUint32 aEventType, nsINode *aNode, PRBool aIsAsynch = PR_FALSE,
              EIsFromUserInput aIsFromUserInput = eAutoDetect,
              EEventRule aEventRule = eRemoveDupes);
   virtual ~nsAccEvent() {}
@@ -119,18 +112,18 @@ public:
 
   NS_DECL_NSIACCESSIBLEEVENT
 
   // nsAccEvent
   PRUint32 GetEventType() const { return mEventType; }
   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();
 
 protected:
   /**
    * Get an accessible from event target node.
    */
   nsAccessible *GetAccessibleForNode() const;
@@ -141,17 +134,17 @@ protected:
    */
   void CaptureIsFromUserInput(EIsFromUserInput aIsFromUserInput);
 
   PRBool mIsFromUserInput;
 
   PRUint32 mEventType;
   EEventRule mEventRule;
   PRPackedBool mIsAsync;
-  nsCOMPtr<nsIAccessible> mAccessible;
+  nsRefPtr<nsAccessible> mAccessible;
   nsCOMPtr<nsINode> mNode;
 
   friend class nsAccEventQueue;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsAccEvent, NS_ACCEVENT_IMPL_CID)
 
 
@@ -162,17 +155,17 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsAccEvent
   0x4358,                                               \
   { 0x86, 0x8c, 0x39, 0x12, 0xb1, 0x5b, 0x76, 0x7a }    \
 }
 
 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)
 
   NS_DECL_ISUPPORTS_INHERITED
 
   /**
    * Return true if event is unconditional, i.e. must be fired.
@@ -191,17 +184,17 @@ private:
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsAccReorderEvent, NS_ACCREORDEREVENT_IMPL_CID)
 
 
 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);
 
   nsAccStateChangeEvent(nsINode *aNode, PRUint32 aState, PRBool aIsExtraState,
                         PRBool aIsEnabled);
 
   nsAccStateChangeEvent(nsINode *aNode, PRUint32 aState, PRBool aIsExtraState);
@@ -214,17 +207,17 @@ private:
   PRBool mIsExtraState;
   PRBool mIsEnabled;
 };
 
 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);
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIACCESSIBLETEXTCHANGEEVENT
 
 private:
@@ -233,30 +226,30 @@ private:
   PRBool mIsInserted;
   nsString mModifiedText;
 };
 
 class nsAccCaretMoveEvent: public nsAccEvent,
                            public nsIAccessibleCaretMoveEvent
 {
 public:
-  nsAccCaretMoveEvent(nsIAccessible *aAccessible, PRInt32 aCaretOffset);
+  nsAccCaretMoveEvent(nsAccessible *aAccessible, PRInt32 aCaretOffset);
   nsAccCaretMoveEvent(nsINode *aNode);
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIACCESSIBLECARETMOVEEVENT
 
 private:
   PRInt32 mCaretOffset;
 };
 
 class nsAccTableChangeEvent : public nsAccEvent,
                               public nsIAccessibleTableChangeEvent {
 public:
-  nsAccTableChangeEvent(nsIAccessible *aAccessible, PRUint32 aEventType,
+  nsAccTableChangeEvent(nsAccessible *aAccessible, PRUint32 aEventType,
                         PRInt32 aRowOrColIndex, PRInt32 aNumRowsOrCols,
                         PRBool aIsAsynch);
 
   NS_DECL_ISUPPORTS
   NS_DECL_NSIACCESSIBLETABLECHANGEEVENT
 
 private:
   PRUint32 mRowOrColIndex;   // the start row/column after which the rows are inserted/deleted.
--- a/accessible/src/base/nsAccUtils.cpp
+++ b/accessible/src/base/nsAccUtils.cpp
@@ -522,17 +522,17 @@ nsAccUtils::IsARIASelected(nsIAccessible
                              nsAccessibilityAtoms::aria_selected,
                              nsAccessibilityAtoms::_true, eCaseMatters))
       return PR_TRUE;
   }
 
   return PR_FALSE;
 }
 
-already_AddRefed<nsIAccessibleText>
+already_AddRefed<nsHyperTextAccessible>
 nsAccUtils::GetTextAccessibleFromSelection(nsISelection *aSelection,
                                            nsINode **aNode)
 {
   // Get accessible from selection's focus DOM point (the DOM point where
   // selection is ended).
 
   nsCOMPtr<nsIDOMNode> focusDOMNode;
   aSelection->GetFocusNode(getter_AddRefs(focusDOMNode));
@@ -549,17 +549,17 @@ nsAccUtils::GetTextAccessibleFromSelecti
   // Get text accessible containing the result node.
   while (resultNode) {
     // Make sure to get the correct starting node for selection events inside
     // XBL content trees.
     resultNode = GetAccService()->GetRelevantContentNodeFor(resultNode);
     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)
             NS_ADDREF(*aNode = resultNode);
 
           return textAcc;
         }
       }
--- a/accessible/src/base/nsAccUtils.h
+++ b/accessible/src/base/nsAccUtils.h
@@ -54,16 +54,17 @@
 #include "nsIDocShell.h"
 #include "nsIDOMNode.h"
 #include "nsIPersistentProperties2.h"
 #include "nsIPresShell.h"
 #include "nsPoint.h"
 
 class nsAccessNode;
 class nsAccessible;
+class nsHyperTextAccessible;
 class nsHTMLTableAccessible;
 class nsDocAccessible;
 #ifdef MOZ_XUL
 class nsXULTreeAccessible;
 #endif
 
 class nsAccUtils
 {
@@ -233,17 +234,17 @@ public:
   /**
    * Return text accessible containing focus point of the given selection.
    * Used for normal and misspelling selection changes processing.
    *
    * @param aSelection  [in] the given selection
    * @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);
 
   /**
    * Converts the given coordinates to coordinates relative screen.
    *
    * @param aX               [in] the given x coord
    * @param aY               [in] the given y coord
--- a/accessible/src/base/nsAccessibilityService.cpp
+++ b/accessible/src/base/nsAccessibilityService.cpp
@@ -176,17 +176,18 @@ nsAccessibilityService::NotifyOfAnchorJu
                                targetNode);
 }
 
 // nsIAccessibilityService
 nsresult
 nsAccessibilityService::FireAccessibleEvent(PRUint32 aEvent,
                                             nsIAccessible *aTarget)
 {
-  nsEventShell::FireEvent(aEvent, aTarget);
+  nsRefPtr<nsAccessible> accessible(do_QueryObject(aTarget));
+  nsEventShell::FireEvent(aEvent, accessible);
   return NS_OK;
 }
 
 // nsAccessibilityService private
 nsresult
 nsAccessibilityService::GetInfo(nsIFrame *aFrame, nsIWeakReference **aShell,
                                 nsIContent **aContent)
 {
--- a/accessible/src/base/nsCaretAccessible.cpp
+++ b/accessible/src/base/nsCaretAccessible.cpp
@@ -241,17 +241,17 @@ nsCaretAccessible::NormalSelectionChange
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (rangeCount == 0) {
     mLastTextAccessible = nsnull;
     return NS_OK; // No selection
   }
 
   nsCOMPtr<nsINode> textNode;
-  nsCOMPtr<nsIAccessibleText> textAcc =
+  nsRefPtr<nsHyperTextAccessible> textAcc =
     nsAccUtils::GetTextAccessibleFromSelection(aSel, getter_AddRefs(textNode));
   NS_ENSURE_STATE(textAcc);
 
   PRInt32 caretOffset;
   rv = textAcc->GetCaretOffset(&caretOffset);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (textAcc == mLastTextAccessible && caretOffset == mLastCaretOffset) {
@@ -276,25 +276,23 @@ nsCaretAccessible::SpellcheckSelectionCh
                                               nsISelection *aSel)
 {
   // XXX: fire an event for accessible of focus node of the selection. If
   // spellchecking is enabled then we will fire the number of events for
   // the same accessible for newly appended range of the selection (for every
   // 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;
 }
 
 nsIntRect
 nsCaretAccessible::GetCaretRect(nsIWidget **aOutWidget)
 {
--- a/accessible/src/base/nsDocAccessible.cpp
+++ b/accessible/src/base/nsDocAccessible.cpp
@@ -1128,18 +1128,17 @@ nsDocAccessible::ARIAAttributeChanged(ns
     nsRefPtr<nsAccEvent> event =
       new nsAccStateChangeEvent(aContent, kState, PR_FALSE);
     FireDelayedAccessibleEvent(event);
     if (aContent == gLastFocusedNode) {
       // State changes for MIXED state currently only supported for focused item, because
       // 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  =
           (nsAccUtils::State(accessible) & nsIAccessibleStates::STATE_MIXED) != 0;
         if (wasMixed != isMixed) {
           nsRefPtr<nsAccEvent> event =
             new nsAccStateChangeEvent(aContent,
                                       nsIAccessibleStates::STATE_MIXED,
@@ -1291,24 +1290,24 @@ nsDocAccessible::HandleAccEvent(nsAccEve
 ////////////////////////////////////////////////////////////////////////////////
 // Public members
 
 
 ////////////////////////////////////////////////////////////////////////////////
 // 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);
 }
 
 void
 nsDocAccessible::FireTextChangeEventForText(nsIContent *aContent,
                                             CharacterDataChangeInfo* aInfo,
                                             PRBool aIsInserted)
@@ -1471,20 +1470,17 @@ nsDocAccessible::FireDelayedAccessibleEv
     mEventQueue->Push(aEvent);
 
   return NS_OK;
 }
 
 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();
   EIsFromUserInput isFromUserInput =
     aEvent->IsFromUserInput() ? eFromUserInput : eNoUserInput;
 
   PRBool isAsync = aEvent->IsAsync();
 
--- a/accessible/src/base/nsDocAccessible.h
+++ b/accessible/src/base/nsDocAccessible.h
@@ -306,20 +306,21 @@ protected:
    * @param  aIsFromUserInput  [in] the event is known to be from user input
    */
   nsresult FireShowHideEvents(nsINode *aDOMNode, PRBool aAvoidOnThisNode,
                               PRUint32 aEventType,
                               EEventFiringType aDelayedOrNormal,
                               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;
     nsCOMPtr<nsIDocument> mDocument;
     nsCOMPtr<nsITimer> mScrollWatchTimer;
     PRUint16 mScrollPositionChangedTicks; // Used for tracking scroll events
 
 protected:
--- a/accessible/src/base/nsEventShell.cpp
+++ b/accessible/src/base/nsEventShell.cpp
@@ -47,32 +47,32 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 void
 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) {
     sEventTargetNode = node;
     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,);
 
   nsRefPtr<nsAccEvent> event = new nsAccEvent(aEventType, aAccessible,
                                               aIsAsynch, aIsFromUserInput);
 
   FireEvent(event);
--- a/accessible/src/base/nsEventShell.h
+++ b/accessible/src/base/nsEventShell.h
@@ -62,17 +62,17 @@ public:
   /**
    * Fire accessible event of the given type for the given accessible.
    *
    * @param  aEventType   [in] the event type
    * @param  aAccessible  [in] the event target
    * @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);
 
   /**
    * Append 'event-from-input' object attribute if the accessible event has
    * been fired just now for the given node.
    *
    * @param  aNode        [in] the DOM node
--- a/accessible/src/mac/nsAccessibleWrap.mm
+++ b/accessible/src/mac/nsAccessibleWrap.mm
@@ -179,18 +179,17 @@ nsAccessibleWrap::FirePlatformEvent(nsAc
 
   PRUint32 eventType = aEvent->GetEventType();
 
   // ignore everything but focus-changed and value-changed events for now.
   if (eventType != nsIAccessibleEvent::EVENT_FOCUS &&
       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;
   accessible->GetNativeInterface((void**)&nativeAcc);
   if (!nativeAcc)
     return NS_ERROR_FAILURE;
 
   switch (eventType) {
--- a/accessible/src/msaa/nsAccessibleWrap.cpp
+++ b/accessible/src/msaa/nsAccessibleWrap.cpp
@@ -1661,36 +1661,35 @@ nsAccessibleWrap::FirePlatformEvent(nsAc
 
   PRUint32 winEvent = gWinEventMap[eventType];
   if (!winEvent)
     return NS_OK;
 
   // 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;
 
   if (eventType == nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED ||
       eventType == nsIAccessibleEvent::EVENT_FOCUS) {
     UpdateSystemCaret();
   }
  
   PRInt32 childID = GetChildIDFor(accessible); // get the id for the accessible
   if (!childID)
     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;
   }
 
   HWND hWnd = GetHWNDFor(newAccessible);
   NS_ENSURE_TRUE(hWnd, NS_ERROR_FAILURE);
 
   // Gecko uses two windows for every scrollable area. One window contains
--- a/accessible/src/msaa/nsHyperTextAccessibleWrap.cpp
+++ b/accessible/src/msaa/nsHyperTextAccessibleWrap.cpp
@@ -52,20 +52,19 @@ IMPL_IUNKNOWN_INHERITED2(nsHyperTextAcce
 
 nsresult
 nsHyperTextAccessibleWrap::HandleAccEvent(nsAccEvent *aEvent)
 {
   PRUint32 eventType = aEvent->GetEventType();
 
   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,
                                                           &instancePtr);
         if (NS_SUCCEEDED(rv)) {
           NS_IF_RELEASE(gTextEvent);
 
           CallQueryInterface(aEvent, &gTextEvent);