Fix for bug 377617 - get rid of AtkTextChange struct, r=ginn.chen
authorsurkov.alexander@gmail.com
Mon, 16 Apr 2007 23:52:52 -0700
changeset 582 54f283fe7b8a87bccde276b2772618a29c9a4a0a
parent 581 02c5cf1bc12e0a983fe11d4804cfc8cbc842af0f
child 583 b5948813c90b6636731d56472488e385b3041eca
push id1
push userbsmedberg@mozilla.com
push dateThu, 20 Mar 2008 16:49:24 +0000
treeherdermozilla-central@61007906a1f8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersginn.chen
bugs377617
milestone1.9a4pre
Fix for bug 377617 - get rid of AtkTextChange struct, r=ginn.chen
accessible/public/nsIAccessibleEvent.idl
accessible/src/atk/nsAccessibleWrap.cpp
accessible/src/atk/nsDocAccessibleWrap.cpp
accessible/src/base/nsAccessibleEventData.cpp
accessible/src/base/nsAccessibleEventData.h
accessible/src/html/nsHyperTextAccessible.cpp
accessible/src/html/nsHyperTextAccessible.h
--- a/accessible/public/nsIAccessibleEvent.idl
+++ b/accessible/public/nsIAccessibleEvent.idl
@@ -516,8 +516,28 @@ interface nsIAccessibleStateChangeEvent 
   boolean isExtraState();
 
   /**
    * Returns true if the state is turned on.
    */
   boolean isEnabled();
 };
 
+
+[scriptable, uuid(50a1e151-8e5f-4bcc-aaaf-a4bed1190e93)]
+interface nsIAccessibleTextChangeEvent : nsIAccessibleEvent
+{
+  /**
+   * Returns offset of changed text in accessible.
+   */
+  readonly attribute long start;
+
+  /**
+   * Returns length of changed text.
+   */
+  readonly attribute unsigned long length;
+
+  /**
+   * Returns true if text was inserted, otherwise false.
+   */
+  boolean isInserted();
+};
+
--- a/accessible/src/atk/nsAccessibleWrap.cpp
+++ b/accessible/src/atk/nsAccessibleWrap.cpp
@@ -1071,13 +1071,36 @@ nsAccessibleWrap::FireAccessibleEvent(ns
               // Fire state change for first state if there is one to map
               atk_object_notify_state_change(atkObj,
                                              atkStateMap[stateIndex].atkState,
                                              isEnabled);
             }
         }
         break;
       }
+
+    case nsIAccessibleEvent::EVENT_TEXT_CHANGED:
+        MAI_LOG_DEBUG(("\n\nReceived: EVENT_TEXT_CHANGED\n"));
+
+        nsCOMPtr<nsIAccessibleTextChangeEvent> event =
+          do_QueryInterface(aEvent);
+        NS_ENSURE_TRUE(event, NS_ERROR_FAILURE);
+
+        PRInt32 start = 0;
+        event->GetStart(&start);
+
+        PRUint32 length = 0;
+        event->GetLength(&length);
+
+        PRBool isInserted;
+        event->IsInserted(&isInserted);
+
+        g_signal_emit_by_name (atkObj,
+                               isInserted ? \
+                               "text_changed::insert":"text_changed::delete",
+                               start,
+                               length);
+        break;
     }
 
     return NS_OK;
 }
 
--- a/accessible/src/atk/nsDocAccessibleWrap.cpp
+++ b/accessible/src/atk/nsDocAccessibleWrap.cpp
@@ -203,33 +203,16 @@ NS_IMETHODIMP nsDocAccessibleWrap::FireT
         break;
 
     case nsIAccessibleEvent::EVENT_SELECTION_CHANGED:
         MAI_LOG_DEBUG(("\n\nReceived: EVENT_SELECTION_CHANGED\n"));
         g_signal_emit_by_name(atkObj, "selection_changed");
         rv = NS_OK;
         break;
 
-    case nsIAccessibleEvent::EVENT_TEXT_CHANGED:
-        AtkTextChange *pAtkTextChange;
-
-        MAI_LOG_DEBUG(("\n\nReceived: EVENT_TEXT_CHANGED\n"));
-        NS_ASSERTION(aEventData, "Event needs event data");
-        if (!aEventData)
-            break;
-
-        pAtkTextChange = NS_REINTERPRET_CAST(AtkTextChange *, aEventData);
-        g_signal_emit_by_name (atkObj,
-                               pAtkTextChange->add ? \
-                               "text_changed::insert":"text_changed::delete",
-                               pAtkTextChange->start,
-                               pAtkTextChange->length);
-        rv = NS_OK;
-        break;
-
     case nsIAccessibleEvent::EVENT_TEXT_SELECTION_CHANGED:
         MAI_LOG_DEBUG(("\n\nReceived: EVENT_TEXT_SELECTION_CHANGED\n"));
         g_signal_emit_by_name(atkObj, "text_selection_changed");
         rv = NS_OK;
         break;
 
     case nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED:
         MAI_LOG_DEBUG(("\n\nReceived: EVENT_TEXT_CARET_MOVED\n"));
--- a/accessible/src/base/nsAccessibleEventData.cpp
+++ b/accessible/src/base/nsAccessibleEventData.cpp
@@ -175,8 +175,42 @@ nsAccStateChangeEvent::IsExtraState(PRBo
 
 NS_IMETHODIMP
 nsAccStateChangeEvent::IsEnabled(PRBool *aIsEnabled)
 {
   *aIsEnabled = mIsEnabled;
   return NS_OK;
 }
 
+
+// nsAccStateChangeEvent
+NS_IMPL_ISUPPORTS_INHERITED1(nsAccTextChangeEvent, nsAccEvent,
+                             nsIAccessibleTextChangeEvent)
+
+nsAccTextChangeEvent::
+  nsAccTextChangeEvent(nsIAccessible *aAccessible,
+                       PRInt32 aStart, PRUint32 aLength, PRBool aIsInserted):
+  nsAccEvent(::nsIAccessibleEvent::EVENT_TEXT_CHANGED, aAccessible, nsnull),
+  mStart(aStart), mLength(aLength), mIsInserted(mIsInserted)
+{
+}
+
+NS_IMETHODIMP
+nsAccTextChangeEvent::GetStart(PRInt32 *aStart)
+{
+  *aStart = mStart;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsAccTextChangeEvent::GetLength(PRUint32 *aLength)
+{
+  *aLength = mLength;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsAccTextChangeEvent::IsInserted(PRBool *aIsInserted)
+{
+  *aIsInserted = mIsInserted;
+  return NS_OK;
+}
+
--- a/accessible/src/base/nsAccessibleEventData.h
+++ b/accessible/src/base/nsAccessibleEventData.h
@@ -86,16 +86,33 @@ public:
   NS_DECL_NSIACCESSIBLESTATECHANGEEVENT
 
 private:
   PRUint32 mState;
   PRBool mIsExtraState;
   PRBool mIsEnabled;
 };
 
+class nsAccTextChangeEvent: public nsAccEvent,
+                            public nsIAccessibleTextChangeEvent
+{
+public:
+  nsAccTextChangeEvent(nsIAccessible *aAccessible,
+                       PRInt32 aStart, PRUint32 aLength, PRBool aIsInserted);
+
+  NS_DECL_ISUPPORTS_INHERITED
+  NS_FORWARD_NSIACCESSIBLEEVENT(nsAccEvent::)
+  NS_DECL_NSIACCESSIBLETEXTCHANGEEVENT
+
+private:
+  PRInt32 mStart;
+  PRUint32 mLength;
+  PRBool mIsInserted;
+};
+
 // XXX todo: We might want to use XPCOM interfaces instead of structs
 //     e.g., nsAccessibleTextChangeEvent: public nsIAccessibleTextChangeEvent
 
 enum AtkProperty {
   PROP_0,           // gobject convention
   PROP_NAME,
   PROP_DESCRIPTION,
   PROP_PARENT,      // ancestry has changed
@@ -118,20 +135,14 @@ struct AtkPropertyChange {
 };
 
 struct AtkChildrenChange {
   PRInt32      index;  // index of child in parent 
   nsIAccessible *child;   
   PRBool        add;    // true for add, false for delete
 };
 
-struct AtkTextChange {
-  PRInt32  start;
-  PRUint32 length;
-  PRBool   add;     // true for add, false for delete
-};
-
 struct AtkTableChange {
   PRUint32 index;   // the start row/column after which the rows are inserted/deleted.
   PRUint32 count;   // the number of inserted/deleted rows/columns
 };
 
 #endif  
--- a/accessible/src/html/nsHyperTextAccessible.cpp
+++ b/accessible/src/html/nsHyperTextAccessible.cpp
@@ -1138,58 +1138,60 @@ NS_IMETHODIMP nsHyperTextAccessible::Wil
 {
   return NS_OK;
 }
 
 NS_IMETHODIMP nsHyperTextAccessible::DidInsertNode(nsIDOMNode *aNode, nsIDOMNode *aParent,
                                                    PRInt32 aPosition, nsresult aResult)
 {
   InvalidateChildren();
-  AtkTextChange textData;
 
-  textData.add = PR_TRUE;
+  PRInt32 start;
+  PRUint32 length = 1;
+  PRBool isInserted = PR_TRUE;
+
   nsCOMPtr<nsIContent> content(do_QueryInterface(aNode));
   if (content && content->IsNodeOfType(nsINode::eTEXT)) {
-    textData.length = content->TextLength();
-    if (!textData.length) {
+    length = content->TextLength();
+    if (!length)
       return NS_OK;
-    }
   }
   else {
     // Don't fire event for the first br
     nsCOMPtr<nsIEditor> editor = GetEditor();
     if (editor) {
       PRBool isEmpty;
       editor->GetDocumentIsEmpty(&isEmpty);
       if (isEmpty) {
         return NS_OK;
       }
     }
-    
-    textData.length = 1;
   }
 
-  if (NS_FAILED(DOMPointToOffset(aNode, aPosition, &textData.start))) {
+  if (NS_FAILED(DOMPointToOffset(aNode, aPosition, &start)))
     return NS_OK;
-  }
-  return FireTextChangeEvent(&textData);
+
+  nsCOMPtr<nsIAccessibleTextChangeEvent> event =
+    new nsAccTextChangeEvent(this, start, length, isInserted);
+  NS_ENSURE_TRUE(event, NS_ERROR_OUT_OF_MEMORY);
+
+  return FireAccessibleEvent(event);
 }
 
 NS_IMETHODIMP nsHyperTextAccessible::WillDeleteNode(nsIDOMNode *aChild)
 {
-  AtkTextChange textData;
+  PRInt32 start;
+  PRUint32 length = 1;
+  PRBool isInserted = PR_FALSE;
 
-  textData.add = PR_FALSE;
-  textData.length = 1;
   nsCOMPtr<nsIContent> content(do_QueryInterface(aChild));
   if (content && content->IsNodeOfType(nsINode::eTEXT)) {
-    textData.length = content->TextLength();
-    if (!textData.length) {
+    length = content->TextLength();
+    if (!length)
       return NS_OK;
-    }
   }
   else {
     // Don't fire event for the last br
     nsCOMPtr<nsIEditor> editor = GetEditor();
     if (editor) {
       PRBool isEmpty;
       editor->GetDocumentIsEmpty(&isEmpty);
       if (isEmpty) {
@@ -1199,20 +1201,24 @@ NS_IMETHODIMP nsHyperTextAccessible::Wil
   }
 
   nsCOMPtr<nsIDOMNode> parentNode;
   aChild->GetParentNode(getter_AddRefs(parentNode));
   nsCOMPtr<nsIContent> parentContent(do_QueryInterface(parentNode));
   NS_ENSURE_TRUE(parentContent, NS_ERROR_FAILURE);
   nsCOMPtr<nsIContent> childContent(do_QueryInterface(aChild));
   NS_ENSURE_TRUE(childContent, NS_ERROR_FAILURE);
-  if (NS_FAILED(DOMPointToOffset(parentNode, parentContent->IndexOf(childContent), &textData.start))) {
+  if (NS_FAILED(DOMPointToOffset(parentNode, parentContent->IndexOf(childContent), &start)))
     return NS_OK;
-  }
-  return FireTextChangeEvent(&textData);
+
+  nsCOMPtr<nsIAccessibleTextChangeEvent> event =
+    new nsAccTextChangeEvent(this, start, length, isInserted);
+  NS_ENSURE_TRUE(event, NS_ERROR_OUT_OF_MEMORY);
+
+  return FireAccessibleEvent(event);
 }
 
 NS_IMETHODIMP nsHyperTextAccessible::DidDeleteNode(nsIDOMNode *aChild, nsresult aResult)
 {
   return InvalidateChildren();
 }
 
 NS_IMETHODIMP nsHyperTextAccessible::WillSplitNode(nsIDOMNode *aExistingRightNode, PRInt32 aOffset)
@@ -1242,84 +1248,81 @@ NS_IMETHODIMP nsHyperTextAccessible::Wil
                                                     PRInt32 aOffset, const nsAString& aString)
 {
   return NS_OK;
 }
 
 NS_IMETHODIMP nsHyperTextAccessible::DidInsertText(nsIDOMCharacterData *aTextNode, PRInt32 aOffset,
                                                    const nsAString& aString, nsresult aResult)
 {
-  AtkTextChange textData;
+  PRInt32 start;
+  PRUint32 length = aString.Length();
+  PRBool isInserted = PR_TRUE;
 
-  textData.add = PR_TRUE;
-  textData.length = aString.Length();
-  if (NS_FAILED(DOMPointToOffset(aTextNode, aOffset, &textData.start))) {
+  if (NS_FAILED(DOMPointToOffset(aTextNode, aOffset, &start)))
     return NS_OK;
-  }
-  return FireTextChangeEvent(&textData);
+
+  nsCOMPtr<nsIAccessibleTextChangeEvent> event =
+    new nsAccTextChangeEvent(this, start, length, isInserted);
+  NS_ENSURE_TRUE(event, NS_ERROR_OUT_OF_MEMORY);
+
+  return FireAccessibleEvent(event);
 }
 
 NS_IMETHODIMP nsHyperTextAccessible::WillDeleteText(nsIDOMCharacterData *aTextNode,
                                                     PRInt32 aOffset, PRInt32 aLength)
 {
-  AtkTextChange textData;
+  PRInt32 start;
+  PRUint32 length = aLength;
+  PRBool isInserted = PR_FALSE;
 
-  textData.add = PR_FALSE;
-  textData.length = aLength;
-  if (NS_FAILED(DOMPointToOffset(aTextNode, aOffset, &textData.start))) {
+  if (NS_FAILED(DOMPointToOffset(aTextNode, aOffset, &start)))
     return NS_OK;
-  }
-  return FireTextChangeEvent(&textData);
+
+  nsCOMPtr<nsIAccessibleTextChangeEvent> event =
+    new nsAccTextChangeEvent(this, start, length, isInserted);
+  NS_ENSURE_TRUE(event, NS_ERROR_OUT_OF_MEMORY);
+
+  return FireAccessibleEvent(event);
 }
 
 NS_IMETHODIMP nsHyperTextAccessible::DidDeleteText(nsIDOMCharacterData *aTextNode, PRInt32 aOffset,
                                                    PRInt32 aLength, nsresult aResult)
 {
   return NS_OK;
 }
 
 NS_IMETHODIMP nsHyperTextAccessible::WillDeleteSelection(nsISelection *aSelection)
 // <input> & <textarea> fires this event while deleting text
 // <editor> fires WillDeleteText/WillDeleteNode instead
 // XXX Deal with > 1 selections
 {
   PRInt32 selectionStart, selectionEnd;
   GetSelectionBounds(0, &selectionStart, &selectionEnd);
 
-  AtkTextChange textData;
+  PRInt32 start = PR_MIN(selectionStart, selectionEnd);;
+  PRUint32 length = PR_ABS(selectionEnd - selectionStart);
+  PRBool isInserted = PR_FALSE;
 
-  textData.add = PR_FALSE;
-  textData.start = PR_MIN(selectionStart, selectionEnd);
-  textData.length = PR_ABS(selectionEnd - selectionStart);
-  return FireTextChangeEvent(&textData);
+  nsCOMPtr<nsIAccessibleTextChangeEvent> event =
+    new nsAccTextChangeEvent(this, start, length, isInserted);
+  NS_ENSURE_TRUE(event, NS_ERROR_OUT_OF_MEMORY);
+
+  return FireAccessibleEvent(event);
 }
 
 NS_IMETHODIMP nsHyperTextAccessible::DidDeleteSelection(nsISelection *aSelection)
 {
   return NS_OK;
 }
 
 /**
   * =================== Caret & Selection ======================
   */
 
-nsresult nsHyperTextAccessible::FireTextChangeEvent(AtkTextChange *aTextData)
-{
-  nsCOMPtr<nsIAccessible> accessible(do_QueryInterface(NS_STATIC_CAST(nsIAccessibleText*, this)));
-  nsCOMPtr<nsPIAccessible> privAccessible(do_QueryInterface(accessible));
-  if (privAccessible) {
-#ifdef DEBUG_A11Y
-    printf("  [start=%d, length=%d, add=%d]\n", aTextData->start, aTextData->length, aTextData->add);
-#endif
-    privAccessible->FireToolkitEvent(nsIAccessibleEvent::EVENT_TEXT_CHANGED,
-                                     accessible, aTextData);
-  }
-  return NS_OK;
-}
-
 nsresult nsHyperTextAccessible::SetSelectionRange(PRInt32 aStartPos, PRInt32 aEndPos)
 {
   // Set the selection
   nsresult rv = SetSelectionBounds(0, aStartPos, aEndPos);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // If range 0 was successfully set, clear any additional selection 
   // ranges remaining from previous selection
--- a/accessible/src/html/nsHyperTextAccessible.h
+++ b/accessible/src/html/nsHyperTextAccessible.h
@@ -140,13 +140,11 @@ protected:
 
   // Editor helpers, subclasses of nsHyperTextAccessible may have editor
   virtual void SetEditor(nsIEditor *aEditor) { return; }
   virtual already_AddRefed<nsIEditor> GetEditor() { return nsnull; }
 
   // Selection helpers
   nsresult GetSelections(nsISelectionController **aSelCon, nsISelection **aDomSel);
   nsresult SetSelectionRange(PRInt32 aStartPos, PRInt32 aEndPos);
+};
 
-  // Event helpers
-  nsresult FireTextChangeEvent(AtkTextChange *aTextData);
-};
 #endif  // _nsHyperTextAccessible_H_