bug 1213402 - separate value change events into text value changes and numeric value changes r=davidb
authorTrevor Saunders <tbsaunde@tbsaunde.org>
Mon, 02 Nov 2015 15:34:51 -0500
changeset 272031 72f55d458dd63051f804e016b94cc1dfcca9bdcb
parent 272030 a3f9ac7c8454439cbd17ba3c4cf08bf5da33484a
child 272032 5a3d821ef31be556aa4a5a11708205e6cd52ae04
push id29659
push usercbook@mozilla.com
push dateWed, 11 Nov 2015 11:43:09 +0000
treeherdermozilla-central@84a7cf29f4f1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdavidb
bugs1213402
milestone45.0a1
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 1213402 - separate value change events into text value changes and numeric value changes r=davidb Arguably these are different things, and it will be easier to proxy events for atk this way because atk only wants the numeric value changes.
accessible/atk/AccessibleWrap.cpp
accessible/base/nsAccessibilityService.h
accessible/generic/DocAccessible-inl.h
accessible/generic/DocAccessible.cpp
accessible/generic/RootAccessible.cpp
accessible/interfaces/nsIAccessibleCaretMoveEvent.idl
accessible/interfaces/nsIAccessibleEvent.idl
accessible/interfaces/nsIAccessibleHideEvent.idl
accessible/interfaces/nsIAccessibleObjectAttributeChangedEvent.idl
accessible/interfaces/nsIAccessibleStateChangeEvent.idl
accessible/interfaces/nsIAccessibleTableChangeEvent.idl
accessible/interfaces/nsIAccessibleTextChangeEvent.idl
accessible/interfaces/nsIAccessibleVirtualCursorChangeEvent.idl
accessible/jsat/EventManager.jsm
accessible/mac/AccessibleWrap.mm
accessible/mac/Platform.mm
accessible/tests/mochitest/events.js
accessible/tests/mochitest/events/test_text.html
accessible/tests/mochitest/events/test_valuechange.html
accessible/windows/msaa/nsEventMap.h
--- a/accessible/atk/AccessibleWrap.cpp
+++ b/accessible/atk/AccessibleWrap.cpp
@@ -1240,16 +1240,17 @@ AccessibleWrap::HandleAccEvent(AccEvent*
         accessible->Name(newName);
 
         MaybeFireNameChange(atkObj, newName);
 
         break;
       }
 
   case nsIAccessibleEvent::EVENT_VALUE_CHANGE:
+  case nsIAccessibleEvent::EVENT_TEXT_VALUE_CHANGE:
     if (accessible->HasNumericValue()) {
       // Make sure this is a numeric value. Don't fire for string value changes
       // (e.g. text editing) ATK values are always numeric.
       g_object_notify((GObject*)atkObj, "accessible-value");
     }
     break;
 
     case nsIAccessibleEvent::EVENT_SELECTION:
--- a/accessible/base/nsAccessibilityService.h
+++ b/accessible/base/nsAccessibilityService.h
@@ -380,12 +380,13 @@ static const char kEventTypeNames[][40] 
   "hyperlink selected link changed",         // EVENT_HYPERLINK_SELECTED_LINK_CHANGED
   "hypertext link activated",                // EVENT_HYPERTEXT_LINK_ACTIVATED
   "hypertext link selected",                 // EVENT_HYPERTEXT_LINK_SELECTED
   "hyperlink start index changed",           // EVENT_HYPERLINK_START_INDEX_CHANGED
   "hypertext changed",                       // EVENT_HYPERTEXT_CHANGED
   "hypertext links count changed",           // EVENT_HYPERTEXT_NLINKS_CHANGED
   "object attribute changed",                // EVENT_OBJECT_ATTRIBUTE_CHANGED
   "virtual cursor changed"                   // EVENT_VIRTUALCURSOR_CHANGED
+  "text value change",                       // EVENT_TEXT_VALUE_CHANGE
 };
 
 #endif /* __nsIAccessibilityService_h__ */
 
--- a/accessible/generic/DocAccessible-inl.h
+++ b/accessible/generic/DocAccessible-inl.h
@@ -119,17 +119,17 @@ DocAccessible::NotifyOfLoad(uint32_t aLo
   }
 }
 
 inline void
 DocAccessible::MaybeNotifyOfValueChange(Accessible* aAccessible)
 {
   a11y::role role = aAccessible->Role();
   if (role == roles::ENTRY || role == roles::COMBOBOX)
-    FireDelayedEvent(nsIAccessibleEvent::EVENT_VALUE_CHANGE, aAccessible);
+    FireDelayedEvent(nsIAccessibleEvent::EVENT_TEXT_VALUE_CHANGE, aAccessible);
 }
 
 inline Accessible*
 DocAccessible::GetAccessibleEvenIfNotInMapOrContainer(nsINode* aNode) const
 {
   Accessible* acc = GetAccessibleEvenIfNotInMap(aNode);
   return acc ? acc : GetContainerAccessible(aNode);
 }
--- a/accessible/generic/DocAccessible.cpp
+++ b/accessible/generic/DocAccessible.cpp
@@ -1034,23 +1034,28 @@ DocAccessible::ARIAAttributeChanged(Acce
 
   if (aAttribute == nsGkAtoms::aria_readonly) {
     RefPtr<AccEvent> event =
       new AccStateChangeEvent(aAccessible, states::READONLY);
     FireDelayedEvent(event);
     return;
   }
 
-  // Fire value change event whenever aria-valuetext is changed, or
-  // when aria-valuenow is changed and aria-valuetext is empty
-  if (aAttribute == nsGkAtoms::aria_valuetext ||
-      (aAttribute == nsGkAtoms::aria_valuenow &&
-       (!elm->HasAttr(kNameSpaceID_None, nsGkAtoms::aria_valuetext) ||
-        elm->AttrValueIs(kNameSpaceID_None, nsGkAtoms::aria_valuetext,
-                         nsGkAtoms::_empty, eCaseMatters)))) {
+  // Fire text value change event whenever aria-valuetext is changed.
+  if (aAttribute == nsGkAtoms::aria_valuetext) {
+    FireDelayedEvent(nsIAccessibleEvent::EVENT_TEXT_VALUE_CHANGE, aAccessible);
+    return;
+  }
+
+  // Fire numeric value change event when aria-valuenow is changed and
+  // aria-valuetext is empty
+  if (aAttribute == nsGkAtoms::aria_valuenow &&
+      (!elm->HasAttr(kNameSpaceID_None, nsGkAtoms::aria_valuetext) ||
+       elm->AttrValueIs(kNameSpaceID_None, nsGkAtoms::aria_valuetext,
+                        nsGkAtoms::_empty, eCaseMatters))) {
     FireDelayedEvent(nsIAccessibleEvent::EVENT_VALUE_CHANGE, aAccessible);
     return;
   }
 
   if (aAttribute == nsGkAtoms::aria_owns) {
     mNotificationController->ScheduleRelocation(aAccessible);
   }
 }
--- a/accessible/generic/RootAccessible.cpp
+++ b/accessible/generic/RootAccessible.cpp
@@ -447,18 +447,20 @@ RootAccessible::ProcessDOMEvent(nsIDOMEv
     FocusMgr()->ActiveItemChanged(nullptr);
 #ifdef A11Y_LOG
     if (logging::IsEnabled(logging::eFocus))
       logging::ActiveItemChangeCausedBy("DOMMenuBarInactive", accessible);
 #endif
   }
   else if (accessible->NeedsDOMUIEvent() &&
            eventType.EqualsLiteral("ValueChange")) {
-     targetDocument->FireDelayedEvent(nsIAccessibleEvent::EVENT_VALUE_CHANGE,
-                                      accessible);
+    uint32_t event = accessible->HasNumericValue()
+      ? nsIAccessibleEvent::EVENT_VALUE_CHANGE
+      : nsIAccessibleEvent::EVENT_TEXT_VALUE_CHANGE;
+     targetDocument->FireDelayedEvent(event, accessible);
   }
 #ifdef DEBUG_DRAGDROPSTART
   else if (eventType.EqualsLiteral("mouseover")) {
     nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_DRAGDROP_START,
                             accessible);
   }
 #endif
 }
--- a/accessible/interfaces/nsIAccessibleCaretMoveEvent.idl
+++ b/accessible/interfaces/nsIAccessibleCaretMoveEvent.idl
@@ -3,16 +3,16 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsIAccessibleEvent.idl"
 
 /**
  * Fired when the caret changes position in text.
  */
-[scriptable, builtinclass, uuid(5675c486-a230-4d85-a4bd-33670826d5ff)]
+[scriptable, builtinclass, uuid(ed1982e4-57d7-41a8-8cd8-9023f809383e)]
 interface nsIAccessibleCaretMoveEvent: nsIAccessibleEvent
 {
   /**
    * Return caret offset.
    */
   readonly attribute long caretOffset;
 };
--- a/accessible/interfaces/nsIAccessibleEvent.idl
+++ b/accessible/interfaces/nsIAccessibleEvent.idl
@@ -20,17 +20,17 @@ interface nsIDOMNode;
  * the event and its target. To listen to in-process accessibility invents,
  * make your object an nsIObserver, and listen for accessible-event by 
  * using code something like this:
  *   nsCOMPtr<nsIObserverService> observerService = 
  *     do_GetService("@mozilla.org/observer-service;1", &rv);
  *   if (NS_SUCCEEDED(rv)) 
  *     rv = observerService->AddObserver(this, "accessible-event", PR_TRUE);
  */
-[scriptable, builtinclass, uuid(7f66a33a-9ed7-4fd4-87a8-e431b0f43368)]
+[scriptable, builtinclass, uuid(20c69a40-6c2c-42a3-a578-6f4473aab9dd)]
 interface nsIAccessibleEvent : nsISupports
 {
   /**
    * An object has been created.
    */
   const unsigned long EVENT_SHOW = 0x0001;
 
   /**
@@ -70,17 +70,17 @@ interface nsIAccessibleEvent : nsISuppor
   const unsigned long EVENT_NAME_CHANGE = 0x0008;
 
   /**
    * An object's Description property has changed.
    */
   const unsigned long EVENT_DESCRIPTION_CHANGE = 0x0009;
 
   /**
-   * An object's Value property has changed.
+   * An object's numeric Value has changed.
    */
   const unsigned long EVENT_VALUE_CHANGE = 0x000A;
 
   /**
    * An object's help has changed.
    */
   const unsigned long EVENT_HELP_CHANGE = 0x000B;
 
@@ -408,19 +408,24 @@ interface nsIAccessibleEvent : nsISuppor
   const unsigned long EVENT_OBJECT_ATTRIBUTE_CHANGED = 0x0055;
 
   /**
    * A cursorable's virtual cursor has changed.
    */
   const unsigned long EVENT_VIRTUALCURSOR_CHANGED = 0x0056;
 
   /**
+   * An object's text Value has changed.
+   */
+  const unsigned long EVENT_TEXT_VALUE_CHANGE = 0x0057;
+
+  /**
    * Help make sure event map does not get out-of-line.
    */
-  const unsigned long EVENT_LAST_ENTRY = 0x0057;
+  const unsigned long EVENT_LAST_ENTRY = 0x0058;
 
   /**
    * The type of event, based on the enumerated event values
    * defined in this interface.
    */
   readonly attribute unsigned long eventType;
   
   /**
--- a/accessible/interfaces/nsIAccessibleHideEvent.idl
+++ b/accessible/interfaces/nsIAccessibleHideEvent.idl
@@ -3,17 +3,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsIAccessibleEvent.idl"
 
 /**
  * Fired when a accessible and its subtree are removed from the tree.
  */
-[scriptable, builtinclass, uuid(a2bd2eca-3afa-489b-afb2-f93ef32ad99c)]
+[scriptable, builtinclass, uuid(2051709a-4e0d-4be5-873d-b49d1dee35fa)]
 interface nsIAccessibleHideEvent: nsIAccessibleEvent
 {
   /**
    * Return an accessible that was a parent of the target.
    */
   readonly attribute nsIAccessible targetParent;
 
   /**
--- a/accessible/interfaces/nsIAccessibleObjectAttributeChangedEvent.idl
+++ b/accessible/interfaces/nsIAccessibleObjectAttributeChangedEvent.idl
@@ -6,16 +6,16 @@
 
 #include "nsIAccessibleEvent.idl"
 
 interface nsIAtom;
 
 /**
  * Fired when an attribute of an accessible changes.
  */
-[scriptable, builtinclass, uuid(4CA96609-23C8-4771-86E7-77C8B651CA24)]
+[scriptable, builtinclass, uuid(ce41add2-096e-4606-b1ca-7408c6d5b4c3)]
 interface nsIAccessibleObjectAttributeChangedEvent : nsIAccessibleEvent
 {
   /**
    * Return the accessible attribute that changed.
    */
   readonly attribute nsIAtom changedAttribute;
 };
--- a/accessible/interfaces/nsIAccessibleStateChangeEvent.idl
+++ b/accessible/interfaces/nsIAccessibleStateChangeEvent.idl
@@ -3,17 +3,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsIAccessibleEvent.idl"
 
 /**
  * Fired when a state of an accessible changes.
  */
-[scriptable, builtinclass, uuid(0d2d77c5-7b16-4a15-8b20-c484ceb5ac0d)]
+[scriptable, builtinclass, uuid(58b74954-1835-46ed-9ccd-c906490106f6)]
 interface nsIAccessibleStateChangeEvent : nsIAccessibleEvent
 {
   /**
    * Returns the state of accessible (see constants declared
    * in nsIAccessibleStates).
    */
   readonly attribute unsigned long state;
 
--- a/accessible/interfaces/nsIAccessibleTableChangeEvent.idl
+++ b/accessible/interfaces/nsIAccessibleTableChangeEvent.idl
@@ -1,16 +1,16 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsIAccessibleEvent.idl"
 
-[scriptable, builtinclass, uuid(df517997-ed52-4ea2-b310-2f8e0fe64572)]
+[scriptable, builtinclass, uuid(9fb3a8a4-d254-43d3-80a5-20e171d52b21)]
 interface nsIAccessibleTableChangeEvent: nsIAccessibleEvent
 {
   /**
    * Return the row or column index.
    */
   readonly attribute long rowOrColIndex;
 
   /**
--- a/accessible/interfaces/nsIAccessibleTextChangeEvent.idl
+++ b/accessible/interfaces/nsIAccessibleTextChangeEvent.idl
@@ -3,17 +3,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsIAccessibleEvent.idl"
 
 /**
  * Fired when an accessible's text changes.
  */
-[scriptable, builtinclass, uuid(21e0f8bd-5638-4964-870b-3c8e944ac4c4)]
+[scriptable, builtinclass, uuid(1fcc0dfa-93e6-48f4-bbd4-f80eb1d9f2e6)]
 interface nsIAccessibleTextChangeEvent : nsIAccessibleEvent
 {
   /**
    * Returns offset of changed text in accessible.
    */
   readonly attribute long start;
 
   /**
--- a/accessible/interfaces/nsIAccessibleVirtualCursorChangeEvent.idl
+++ b/accessible/interfaces/nsIAccessibleVirtualCursorChangeEvent.idl
@@ -4,17 +4,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsIAccessibleEvent.idl"
 
 /*
  * An interface for virtual cursor changed events.
  * Passes previous cursor position and text offsets.
  */
-[scriptable, builtinclass, uuid(370e8b9b-2bbc-4bff-a9c7-16ddc54aea21)]
+[scriptable, builtinclass, uuid(a58693b1-009e-4cc9-ae93-9c7d8f85cfdf)]
 interface nsIAccessibleVirtualCursorChangeEvent : nsIAccessibleEvent
 {
   /**
    * Previous object pointed at by virtual cursor. null if none.
    */
   readonly attribute nsIAccessible oldAccessible;
 
   /**
--- a/accessible/jsat/EventManager.jsm
+++ b/accessible/jsat/EventManager.jsm
@@ -297,16 +297,17 @@ this.EventManager.prototype = {
           // positioned inside it.
           break;
         }
         this._preDialogPosition.set(aEvent.accessible.DOMNode, position);
         this.contentControl.autoMove(aEvent.accessible, { delay: 500 });
         break;
       }
       case Events.VALUE_CHANGE:
+      case Events.TEXT_VALUE_CHANGE:
       {
         let position = this.contentControl.vc.position;
         let target = aEvent.accessible;
         if (position === target ||
             Utils.getEmbeddedControl(position) === target) {
           this.present(Presentation.valueChanged(target));
         } else {
           let {liveRegion, isPolite} = this._handleLiveRegion(aEvent,
--- a/accessible/mac/AccessibleWrap.mm
+++ b/accessible/mac/AccessibleWrap.mm
@@ -109,16 +109,17 @@ AccessibleWrap::HandleAccEvent(AccEvent*
   }
 
   uint32_t eventType = aEvent->GetEventType();
 
   // ignore everything but focus-changed, value-changed, caret, selection
   // and document load complete events for now.
   if (eventType != nsIAccessibleEvent::EVENT_FOCUS &&
       eventType != nsIAccessibleEvent::EVENT_VALUE_CHANGE &&
+      eventType != nsIAccessibleEvent::EVENT_TEXT_VALUE_CHANGE &&
       eventType != nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED &&
       eventType != nsIAccessibleEvent::EVENT_TEXT_SELECTION_CHANGED &&
       eventType != nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE)
     return NS_OK;
 
   Accessible* accessible = aEvent->GetAccessible();
   NS_ENSURE_STATE(accessible);
 
@@ -243,16 +244,17 @@ a11y::FireNativeEvent(mozAccessible* aNa
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
 
   switch (aEventType) {
     case nsIAccessibleEvent::EVENT_FOCUS:
       [aNativeAcc didReceiveFocus];
       break;
     case nsIAccessibleEvent::EVENT_VALUE_CHANGE:
+    case nsIAccessibleEvent::EVENT_TEXT_VALUE_CHANGE:
       [aNativeAcc valueDidChange];
       break;
     case nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED:
     case nsIAccessibleEvent::EVENT_TEXT_SELECTION_CHANGED:
       [aNativeAcc selectedTextDidChange];
       break;
     case nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE:
       [aNativeAcc documentLoadComplete];
--- a/accessible/mac/Platform.mm
+++ b/accessible/mac/Platform.mm
@@ -67,16 +67,17 @@ ProxyDestroyed(ProxyAccessible* aProxy)
 
 void
 ProxyEvent(ProxyAccessible* aProxy, uint32_t aEventType)
 {
   // ignore everything but focus-changed, value-changed, caret and selection
   // events for now.
   if (aEventType != nsIAccessibleEvent::EVENT_FOCUS &&
       aEventType != nsIAccessibleEvent::EVENT_VALUE_CHANGE &&
+      aEventType != nsIAccessibleEvent::EVENT_TEXT_VALUE_CHANGE &&
       aEventType != nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED &&
       aEventType != nsIAccessibleEvent::EVENT_TEXT_SELECTION_CHANGED)
     return;
 
   mozAccessible* wrapper = GetNativeFromProxy(aProxy);
   if (wrapper)
     FireNativeEvent(wrapper, aEventType);
 }
--- a/accessible/tests/mochitest/events.js
+++ b/accessible/tests/mochitest/events.js
@@ -23,16 +23,17 @@ const EVENT_SELECTION_WITHIN = nsIAccess
 const EVENT_SHOW = nsIAccessibleEvent.EVENT_SHOW;
 const EVENT_STATE_CHANGE = nsIAccessibleEvent.EVENT_STATE_CHANGE;
 const EVENT_TEXT_ATTRIBUTE_CHANGED = nsIAccessibleEvent.EVENT_TEXT_ATTRIBUTE_CHANGED;
 const EVENT_TEXT_CARET_MOVED = nsIAccessibleEvent.EVENT_TEXT_CARET_MOVED;
 const EVENT_TEXT_INSERTED = nsIAccessibleEvent.EVENT_TEXT_INSERTED;
 const EVENT_TEXT_REMOVED = nsIAccessibleEvent.EVENT_TEXT_REMOVED;
 const EVENT_TEXT_SELECTION_CHANGED = nsIAccessibleEvent.EVENT_TEXT_SELECTION_CHANGED;
 const EVENT_VALUE_CHANGE = nsIAccessibleEvent.EVENT_VALUE_CHANGE;
+const EVENT_TEXT_VALUE_CHANGE = nsIAccessibleEvent.EVENT_TEXT_VALUE_CHANGE;
 const EVENT_VIRTUALCURSOR_CHANGED = nsIAccessibleEvent.EVENT_VIRTUALCURSOR_CHANGED;
 
 const kNotFromUserInput = 0;
 const kFromUserInput = 1;
 
 ////////////////////////////////////////////////////////////////////////////////
 // General
 
--- a/accessible/tests/mochitest/events/test_text.html
+++ b/accessible/tests/mochitest/events/test_text.html
@@ -175,17 +175,18 @@
 
     /**
      * Remove text from HTML input.
      */
     function removeTextFromInput(aID, aStart, aEnd, aText)
     {
       this.__proto__ = new textRemoveInvoker(aID, aStart, aEnd, aText);
 
-      this.eventSeq.push(new invokerChecker(EVENT_VALUE_CHANGE, this.DOMNode));
+      this.eventSeq.push(new invokerChecker(EVENT_TEXT_VALUE_CHANGE,
+                                            this.DOMNode));
 
       this.invoke = function removeTextFromInput_invoke()
       {
         const nsIDOMNSEditableElement =
           Components.interfaces.nsIDOMNSEditableElement;
 
         this.DOMNode.focus();
         this.DOMNode.setSelectionRange(aStart, aEnd);
@@ -202,17 +203,18 @@
 
     /**
      * Add text into HTML input.
      */
     function insertTextIntoInput(aID, aStart, aEnd, aText)
     {
       this.__proto__ = new textInsertInvoker(aID, aStart, aEnd, aText);
 
-      this.eventSeq.push(new invokerChecker(EVENT_VALUE_CHANGE, this.DOMNode));
+      this.eventSeq.push(new invokerChecker(EVENT_TEXT_VALUE_CHANGE,
+                                            this.DOMNode));
 
       this.invoke = function insertTextIntoInput_invoke()
       {
         this.DOMNode.focus();
         synthesizeKey("a", {});
       }
 
       this.getID = function insertTextIntoInput_getID()
--- a/accessible/tests/mochitest/events/test_valuechange.html
+++ b/accessible/tests/mochitest/events/test_valuechange.html
@@ -26,16 +26,20 @@
      * Do tests.
      */
     var gQueue = null;
 
     // Value change invoker
     function changeARIAValue(aNodeOrID, aValuenow, aValuetext)
     {
       this.DOMNode = getNode(aNodeOrID);
+      this.eventSeq = [ new invokerChecker(aValuetext ?
+                                           EVENT_TEXT_VALUE_CHANGE :
+                                           EVENT_VALUE_CHANGE, this.DOMNode)
+        ];
 
       this.invoke = function changeARIAValue_invoke() {
 
         // Note: this should not fire an EVENT_VALUE_CHANGE when aria-valuetext
         // is not empty
         if (aValuenow != undefined)
           this.DOMNode.setAttribute("aria-valuenow", aValuenow);
  
@@ -58,16 +62,19 @@
       this.getID = function changeARIAValue_getID() {
         return prettyName(aNodeOrID) + " value changed";
       }
     }
 
     function changeValue(aID, aValue)
     {
       this.DOMNode = getNode(aID);
+      this.eventSeq = [new invokerChecker(EVENT_TEXT_VALUE_CHANGE,
+                                          this.DOMNode)
+        ];
 
       this.invoke = function changeValue_invoke()
       {
         this.DOMNode.value = aValue;
       }
 
       this.check = function changeValue_check()
       {
@@ -79,16 +86,17 @@
       {
         return prettyName(aID) + " value changed";
       }
     }
 
     function changeProgressValue(aID, aValue)
     {
       this.DOMNode = getNode(aID);
+      this.eventSeq = [new invokerChecker(EVENT_VALUE_CHANGE, this.DOMNode)];
 
       this.invoke = function changeProgressValue_invoke()
       {
          this.DOMNode.value = aValue;
       }
 
       this.check = function changeProgressValue_check()
       {
@@ -100,16 +108,17 @@
       {
         return prettyName(aID) + " value changed";
       }
     }
 
     function changeRangeValue(aID)
     {
       this.DOMNode = getNode(aID);
+      this.eventSeq = [new invokerChecker(EVENT_VALUE_CHANGE, this.DOMNode)];
 
       this.invoke = function changeRangeValue_invoke()
       {
         synthesizeMouse(getNode(aID), 5, 5, { });
       }
 
       this.finalCheck = function changeRangeValue_finalCheck()
       {
@@ -129,17 +138,17 @@
       testValue("slider_vn", "5", 5, 0, 1000, 0);
       testValue("slider_vnvt", "plain", 0, 0, 5, 0);
       testValue("slider_vt", "hi", 0, 0, 3, 0);
       testValue("scrollbar", "5", 5, 0, 1000, 0);
       testValue("progress", "22%", 22, 0, 100, 0);
       testValue("range", "6", 6, 0, 10, 1);
 
       // Test value change events
-      gQueue = new eventQueue(nsIAccessibleEvent.EVENT_VALUE_CHANGE);
+      gQueue = new eventQueue();
 
       gQueue.push(new changeARIAValue("slider_vn", "6", undefined));
       gQueue.push(new changeARIAValue("slider_vt", undefined, "hey!"));
       gQueue.push(new changeARIAValue("slider_vnvt", "3", "sweet"));
       gQueue.push(new changeARIAValue("scrollbar", "6", undefined));
 
       gQueue.push(new changeValue("combobox", "hello"));
 
--- a/accessible/windows/msaa/nsEventMap.h
+++ b/accessible/windows/msaa/nsEventMap.h
@@ -93,10 +93,11 @@ static const uint32_t gWinEventMap[] = {
   IA2_EVENT_HYPERLINK_SELECTED_LINK_CHANGED,         // nsIAccessibleEvent::EVENT_HYPERLINK_SELECTED_LINK_CHANGED
   IA2_EVENT_HYPERTEXT_LINK_ACTIVATED,                // nsIAccessibleEvent::EVENT_HYPERTEXT_LINK_ACTIVATED
   IA2_EVENT_HYPERTEXT_LINK_SELECTED,                 // nsIAccessibleEvent::EVENT_HYPERTEXT_LINK_SELECTED
   IA2_EVENT_HYPERLINK_START_INDEX_CHANGED,           // nsIAccessibleEvent::EVENT_HYPERLINK_START_INDEX_CHANGED
   IA2_EVENT_HYPERTEXT_CHANGED,                       // nsIAccessibleEvent::EVENT_HYPERTEXT_CHANGED
   IA2_EVENT_HYPERTEXT_NLINKS_CHANGED,                // nsIAccessibleEvent::EVENT_HYPERTEXT_NLINKS_CHANGED
   IA2_EVENT_OBJECT_ATTRIBUTE_CHANGED,                // nsIAccessibleEvent::EVENT_OBJECT_ATTRIBUTE_CHANGED
   kEVENT_WIN_UNKNOWN                                 // nsIAccessibleEvent::EVENT_VIRTUALCURSOR_CHANGED
+  EVENT_OBJECT_VALUECHANGE,                          // nsIAccessibleEvent::EVENT_TEXT_VALUE_CHANGE
 };