Bug 423696 - Value change events not fired for text inputs and editable combos, patch=aaronlev, r=me, a=beltzner
authorsurkov.alexander@gmail.com
Wed, 19 Mar 2008 18:58:11 -0700
changeset 13353 5a35cd55fbd579478edd4a04abfc87cb60a727af
parent 13352 631f90312ecd4e827e06d892e0dec265ba994400
child 13354 4f24289cb5a5325a3d2db80e112405adb78a6bf6
push idunknown
push userunknown
push dateunknown
reviewersme, beltzner
bugs423696
milestone1.9b5pre
Bug 423696 - Value change events not fired for text inputs and editable combos, patch=aaronlev, r=me, a=beltzner
accessible/src/base/nsDocAccessible.cpp
accessible/src/base/nsDocAccessible.h
accessible/src/base/nsRootAccessible.cpp
--- a/accessible/src/base/nsDocAccessible.cpp
+++ b/accessible/src/base/nsDocAccessible.cpp
@@ -1293,16 +1293,29 @@ nsDocAccessible::ContentRemoved(nsIDocum
 }
 
 void
 nsDocAccessible::ParentChainChanged(nsIContent *aContent)
 {
 }
 
 void
+nsDocAccessible::FireValueChangeForTextFields(nsIAccessible *aPossibleTextFieldAccessible)
+{
+  if (Role(aPossibleTextFieldAccessible) != nsIAccessibleRole::ROLE_ENTRY)
+    return;
+
+  // Dependent value change event for text changes in textfields
+  nsCOMPtr<nsIAccessibleEvent> valueChangeEvent =
+    new nsAccEvent(nsIAccessibleEvent::EVENT_VALUE_CHANGE, aPossibleTextFieldAccessible,
+                   PR_FALSE, nsAccEvent::eRemoveDupes);
+  FireDelayedAccessibleEvent(valueChangeEvent );
+}
+
+void
 nsDocAccessible::FireTextChangeEventForText(nsIContent *aContent,
                                             CharacterDataChangeInfo* aInfo,
                                             PRBool aIsInserted)
 {
   if (!mIsContentLoaded || !mDocument) {
     return;
   }
 
@@ -1352,16 +1365,18 @@ nsDocAccessible::FireTextChangeEventForT
     if (NS_FAILED(rv))
       return;
 
     nsCOMPtr<nsIAccessibleTextChangeEvent> event =
       new nsAccTextChangeEvent(accessible, offset,
                                renderedEndOffset - renderedStartOffset,
                                aIsInserted, PR_FALSE);
     textAccessible->FireAccessibleEvent(event);
+
+    FireValueChangeForTextFields(accessible);
   }
 }
 
 already_AddRefed<nsIAccessibleTextChangeEvent>
 nsDocAccessible::CreateTextChangeEventForNode(nsIAccessible *aContainerAccessible,
                                               nsIDOMNode *aChangeNode,
                                               nsIAccessible *aAccessibleForChangeNode,
                                               PRBool aIsInserting,
@@ -1942,16 +1957,18 @@ NS_IMETHODIMP nsDocAccessible::Invalidat
       nsCOMPtr<nsIDOMNode> ancestorNode = do_QueryInterface(ancestor);
       if (!ancestorNode) {
         break;
       }
       roleMapEntry = nsAccUtils::GetRoleMapEntry(ancestorNode);
     }
   }
 
+  FireValueChangeForTextFields(containerAccessible);
+
   if (!isShowing) {
     // Fire an event so the assistive technology knows the children have changed
     // This is only used by older MSAA clients. Newer ones should derive this
     // from SHOW and HIDE so that they don't fetch extra objects
     if (childAccessible) {
       nsCOMPtr<nsIAccessibleEvent> reorderEvent =
         new nsAccEvent(nsIAccessibleEvent::EVENT_REORDER, containerAccessible,
                        isAsynch, nsAccEvent::eCoalesceFromSameSubtree);
--- a/accessible/src/base/nsDocAccessible.h
+++ b/accessible/src/base/nsDocAccessible.h
@@ -198,16 +198,21 @@ class nsDocAccessible : public nsHyperTe
      * @param aEventType             event type to fire an event
      * @param aAvoidOnThisNode       Call with PR_TRUE the first time to prevent event firing on root node for change
      * @param aDelay                 whether to fire the event on a delay
      * @param aForceIsFromUserInput  the event is known to be from user input
      */
     nsresult FireShowHideEvents(nsIDOMNode *aDOMNode, PRBool aAvoidOnThisNode, PRUint32 aEventType,
                                 PRBool aDelay, PRBool aForceIsFromUserInput);
 
+    /**
+     * If the given accessible object is a ROLE_ENTRY, fire a value change event for it
+     */
+    void FireValueChangeForTextFields(nsIAccessible *aPossibleTextFieldAccessible);
+
     nsAccessNodeHashtable mAccessNodeCache;
     void *mWnd;
     nsCOMPtr<nsIDocument> mDocument;
     nsCOMPtr<nsITimer> mScrollWatchTimer;
     nsCOMPtr<nsITimer> mFireEventTimer;
     PRUint16 mScrollPositionChangedTicks; // Used for tracking scroll events
     PRPackedBool mIsContentLoaded;
     PRPackedBool mIsLoadCompleteFired;
--- a/accessible/src/base/nsRootAccessible.cpp
+++ b/accessible/src/base/nsRootAccessible.cpp
@@ -919,17 +919,17 @@ nsresult nsRootAccessible::HandleEventWi
     nsAccUtils::FireAccEvent(nsIAccessibleEvent::EVENT_MENU_START, accessible, PR_TRUE);
   }
   else if (eventType.EqualsLiteral("DOMMenuBarInactive")) {  // Always asynch, always from user input
     nsAccEvent::PrepareForEvent(aTargetNode, PR_TRUE);
     nsAccUtils::FireAccEvent(nsIAccessibleEvent::EVENT_MENU_END, accessible, PR_TRUE);
     FireCurrentFocusEvent();
   }
   else if (eventType.EqualsLiteral("ValueChange")) {
-    nsAccUtils::FireAccEvent(nsIAccessibleEvent::EVENT_VALUE_CHANGE, accessible);
+    FireDelayedToolkitEvent(nsIAccessibleEvent::EVENT_VALUE_CHANGE, aTargetNode, nsAccEvent::eRemoveDupes);
   }
 #ifdef DEBUG
   else if (eventType.EqualsLiteral("mouseover")) {
     nsAccUtils::FireAccEvent(nsIAccessibleEvent::EVENT_DRAGDROP_START, accessible);
   }
 #endif
   return NS_OK;
 }