diff --git a/content/base/public/nsIXMLHttpRequest.idl b/content/base/public/nsIXMLHttpRequest.idl
--- a/content/base/public/nsIXMLHttpRequest.idl
+++ b/content/base/public/nsIXMLHttpRequest.idl
@@ -30,25 +30,40 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
-#include "nsISupports.idl"
+#include "nsIDOMEventTarget.idl"
 
 interface nsIChannel;
 interface nsIDOMDocument;
 interface nsIDOMEventListener;
 interface nsIPrincipal;
 interface nsIScriptContext;
 interface nsIVariant;
 interface nsPIDOMWindow;
+
+[scriptable, uuid(6ce0a193-b033-4c3d-b748-f851b09261f5)]
+interface nsIXMLHttpRequestEventTarget : nsIDOMEventTarget {
+  // event handler attributes
+  attribute nsIDOMEventListener onabort;
+  attribute nsIDOMEventListener onerror;
+  attribute nsIDOMEventListener onload;
+  attribute nsIDOMEventListener onloadstart;
+  attribute nsIDOMEventListener onprogress;
+};
+
+[scriptable, uuid(09ff3682-7759-4441-a765-f70e1a1fabcf)]
+interface nsIXMLHttpRequestUpload : nsIXMLHttpRequestEventTarget {
+  // for future use
+};
 
 /**
  * Mozilla's XMLHttpRequest is modelled after Microsoft's IXMLHttpRequest
  * object. The goal has been to make Mozilla's version match Microsoft's
  * version as closely as possible, but there are bound to be some differences.
  *
  * In general, Microsoft's documentation for IXMLHttpRequest can be used.
  * Mozilla's interface definitions provide some additional documentation. The
@@ -85,17 +100,17 @@ interface nsPIDOMWindow;
  * Though actually, if you use addEventListener from C++ weird things will
  * happen too, since the result will depend on what JS happens to be on the
  * stack when you do it....
  *
  * Conclusion: Do not use event listeners on XMLHttpRequest from C++, unless
  * you're aware of all the security implications.  And then think twice about
  * it.
  */
-[scriptable, uuid(acda85ab-d06c-4176-b834-6d129ca97ca3)]
+[scriptable, uuid(aaf12811-45b3-4f10-aac1-41cffa9a6b46)]
 interface nsIXMLHttpRequest : nsISupports
 {
   /**
    * The request uses a channel in order to perform the
    * request.  This attribute represents the channel used
    * for the request.  NULL if the channel has not yet been
    * created.
    *
@@ -318,16 +333,21 @@ interface nsIXMLHttpRequest : nsISupport
    *                  null.
    * @param scriptContext The script context to use for the request. May be
    *                      null.
    * @param ownerWindow The associated window for the request. May be null.
    */
   [noscript] void init(in nsIPrincipal principal,
                        in nsIScriptContext scriptContext,
                        in nsPIDOMWindow ownerWindow);
+
+  /**
+   * Upload process can be tracked by adding event listener to |upload|.
+   */
+  readonly attribute nsIXMLHttpRequestUpload upload;
 };
 
 [scriptable, uuid(261676b4-d508-43bf-b099-74635a0ee2e9)]
 interface nsIJSXMLHttpRequest : nsISupports {
   /**
    * Meant to be a script-only mechanism for setting a load event listener.
    * The attribute is expected to be JavaScript function object. When
    * the load event occurs, the function is invoked.
diff --git a/content/base/src/nsXMLHttpRequest.cpp b/content/base/src/nsXMLHttpRequest.cpp
--- a/content/base/src/nsXMLHttpRequest.cpp
+++ b/content/base/src/nsXMLHttpRequest.cpp
@@ -45,17 +45,16 @@
 #include "nsIURI.h"
 #include "nsILoadGroup.h"
 #include "nsNetUtil.h"
 #include "nsThreadUtils.h"
 #include "nsIUploadChannel.h"
 #include "nsIDOMSerializer.h"
 #include "nsXPCOM.h"
 #include "nsISupportsPrimitives.h"
-#include "nsIEventListenerManager.h"
 #include "nsGUIEvent.h"
 #include "nsIPrivateDOMEvent.h"
 #include "prprf.h"
 #include "nsIDOMEventListener.h"
 #include "nsIJSContextStack.h"
 #include "nsJSEnvironment.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsWeakPtr.h"
@@ -88,16 +87,18 @@
 #include "nsIMultiPartChannel.h"
 #include "nsIScriptObjectPrincipal.h"
 #include "nsIStorageStream.h"
 #include "nsIPromptFactory.h"
 #include "nsIWindowWatcher.h"
 
 #define LOAD_STR "load"
 #define ERROR_STR "error"
+#define ABORT_STR "abort"
+#define LOADSTART_STR "loadstart"
 #define PROGRESS_STR "progress"
 #define UPLOADPROGRESS_STR "uploadprogress"
 #define READYSTATE_STR "readystatechange"
 
 // CIDs
 
 // State
 #define XML_HTTP_REQUEST_UNINITIALIZED  (1 << 0)  // 0
@@ -284,16 +285,305 @@ GetDocumentFromScriptContext(nsIScriptCo
   if (window) {
     nsCOMPtr<nsIDOMDocument> domdoc;
     window->GetDocument(getter_AddRefs(domdoc));
     if (domdoc) {
       CallQueryInterface(domdoc, &doc);
     }
   }
   return doc;
+}
+
+/////////////////////////////////////////////
+
+NS_IMPL_CYCLE_COLLECTION_CLASS(nsXMLHttpRequestUpload)
+
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsXMLHttpRequestUpload)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnLoadListener)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnErrorListener)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnAbortListener)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnLoadStartListener)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnProgressListener)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mListenerManager)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOwner)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsXMLHttpRequestUpload)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnLoadListener)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnErrorListener)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnAbortListener)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnLoadStartListener)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnProgressListener)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mListenerManager)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOwner)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsXMLHttpRequestUpload)
+  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXMLHttpRequestUpload)
+  NS_INTERFACE_MAP_ENTRY(nsIXMLHttpRequestUpload)
+  NS_INTERFACE_MAP_ENTRY(nsPIDOMEventTarget)
+  NS_INTERFACE_MAP_ENTRY(nsIDOMEventTarget)
+  NS_INTERFACE_MAP_ENTRY(nsIDOMNSEventTarget)
+  NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(XMLHttpRequestUpload)
+NS_INTERFACE_MAP_END
+
+NS_IMPL_CYCLE_COLLECTING_ADDREF_AMBIGUOUS(nsXMLHttpRequestUpload,
+                                          nsIXMLHttpRequestUpload)
+NS_IMPL_CYCLE_COLLECTING_RELEASE_AMBIGUOUS(nsXMLHttpRequestUpload,
+                                           nsIXMLHttpRequestUpload)
+
+NS_IMETHODIMP
+nsXMLHttpRequestUpload::AddEventListener(const nsAString& aType,
+                                         nsIDOMEventListener* aListener,
+                                         PRBool aUseCapture)
+{
+  nsCOMPtr<nsIScriptContext> context;
+  GetContextForEventHandlers(getter_AddRefs(context));
+  nsCOMPtr<nsIDocument> doc = GetDocumentFromScriptContext(context);
+  PRBool wantsUntrusted = doc && !nsContentUtils::IsChromeDoc(doc);
+  return AddEventListener(aType, aListener, aUseCapture, wantsUntrusted);
+}
+
+/* void removeEventListener (in string type, in nsIDOMEventListener
+   listener); */
+NS_IMETHODIMP
+nsXMLHttpRequestUpload::RemoveEventListener(const nsAString& aType,
+                                      nsIDOMEventListener* aListener,
+                                      PRBool aUseCapture)
+{
+  nsCOMPtr<nsIEventListenerManager> elm;
+  GetListenerManager(PR_FALSE, getter_AddRefs(elm));
+  if (elm) {
+    PRInt32 flags = aUseCapture ? NS_EVENT_FLAG_CAPTURE : NS_EVENT_FLAG_BUBBLE;
+    elm->RemoveEventListenerByType(aListener, aType, flags, nsnull);
+  }
+
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsXMLHttpRequestUpload::AddEventListener(const nsAString& aType,
+                                         nsIDOMEventListener *aListener,
+                                         PRBool aUseCapture,
+                                         PRBool aWantsUntrusted)
+{
+  nsCOMPtr<nsIEventListenerManager> elm;
+  GetListenerManager(PR_TRUE, getter_AddRefs(elm));
+  NS_ENSURE_STATE(elm);
+  PRInt32 flags = aUseCapture ? NS_EVENT_FLAG_CAPTURE : NS_EVENT_FLAG_BUBBLE;
+  if (aWantsUntrusted) {
+    flags |= NS_PRIV_EVENT_UNTRUSTED_PERMITTED;
+  }
+  return elm->AddEventListenerByType(aListener, aType, flags, nsnull);
+}
+
+NS_IMETHODIMP
+nsXMLHttpRequestUpload::GetScriptTypeID(PRUint32 *aLang)
+{
+  *aLang = mLang;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsXMLHttpRequestUpload::SetScriptTypeID(PRUint32 aLang)
+{
+  mLang = aLang;
+  return NS_OK;
+}
+
+/* boolean dispatchEvent (in nsIDOMEvent evt); */
+NS_IMETHODIMP
+nsXMLHttpRequestUpload::DispatchEvent(nsIDOMEvent* aEvent, PRBool* aRetVal)
+{
+  nsEventStatus status = nsEventStatus_eIgnore;
+  nsresult rv =
+    nsEventDispatcher::DispatchDOMEvent(static_cast<nsPIDOMEventTarget*>(this),
+                                        nsnull, aEvent, nsnull, &status);
+
+  *aRetVal = (status != nsEventStatus_eConsumeNoDefault);
+  return rv;
+}
+
+nsresult
+nsXMLHttpRequestUpload::RemoveAddEventListener(const nsAString& aType,
+                                               nsRefPtr<nsDOMEventListenerWrapper>& aCurrent,
+                                               nsIDOMEventListener* aNew)
+{
+  if (aCurrent) {
+    RemoveEventListener(aType, aCurrent, PR_FALSE);
+    aCurrent = nsnull;
+  }
+  if (aNew) {
+    aCurrent = new nsDOMEventListenerWrapper(aNew);
+    NS_ENSURE_TRUE(aCurrent, NS_ERROR_OUT_OF_MEMORY);
+    AddEventListener(aType, aCurrent, PR_FALSE);
+  }
+  return NS_OK;
+}
+
+nsresult
+nsXMLHttpRequestUpload::GetInnerEventListener(nsRefPtr<nsDOMEventListenerWrapper>& aWrapper,
+                                              nsIDOMEventListener** aListener)
+{
+  NS_ENSURE_ARG_POINTER(aListener);
+  if (aWrapper) {
+    NS_ADDREF(*aListener = aWrapper->GetInner());
+  } else {
+    *aListener = nsnull;
+  }
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsXMLHttpRequestUpload::GetOnload(nsIDOMEventListener** aOnLoad)
+{
+  return GetInnerEventListener(mOnLoadListener, aOnLoad);
+}
+
+NS_IMETHODIMP
+nsXMLHttpRequestUpload::SetOnload(nsIDOMEventListener* aOnLoad)
+{
+  NS_NAMED_LITERAL_STRING(ls, LOAD_STR);
+  return RemoveAddEventListener(ls, mOnLoadListener, aOnLoad);
+}
+
+NS_IMETHODIMP
+nsXMLHttpRequestUpload::GetOnerror(nsIDOMEventListener** aOnerror)
+{
+  return GetInnerEventListener(mOnErrorListener, aOnerror);
+}
+
+NS_IMETHODIMP
+nsXMLHttpRequestUpload::SetOnerror(nsIDOMEventListener* aOnerror)
+{
+  NS_NAMED_LITERAL_STRING(es, ERROR_STR);
+  return RemoveAddEventListener(es, mOnErrorListener, aOnerror);
+}
+
+NS_IMETHODIMP
+nsXMLHttpRequestUpload::GetOnabort(nsIDOMEventListener** aOnabort)
+{
+  return GetInnerEventListener(mOnAbortListener, aOnabort);
+}
+
+NS_IMETHODIMP
+nsXMLHttpRequestUpload::SetOnabort(nsIDOMEventListener* aOnabort)
+{
+  NS_NAMED_LITERAL_STRING(as, ABORT_STR);
+  return RemoveAddEventListener(as, mOnAbortListener, aOnabort);
+}
+
+NS_IMETHODIMP
+nsXMLHttpRequestUpload::GetOnloadstart(nsIDOMEventListener** aOnloadstart)
+{
+  return GetInnerEventListener(mOnLoadStartListener, aOnloadstart);
+}
+
+NS_IMETHODIMP
+nsXMLHttpRequestUpload::SetOnloadstart(nsIDOMEventListener* aOnloadstart)
+{
+  NS_NAMED_LITERAL_STRING(lss, LOADSTART_STR);
+  return RemoveAddEventListener(lss, mOnLoadStartListener, aOnloadstart);
+}
+
+NS_IMETHODIMP
+nsXMLHttpRequestUpload::GetOnprogress(nsIDOMEventListener** aOnprogress)
+{
+  return GetInnerEventListener(mOnProgressListener, aOnprogress);
+}
+
+NS_IMETHODIMP
+nsXMLHttpRequestUpload::SetOnprogress(nsIDOMEventListener* aOnprogress)
+{
+  NS_NAMED_LITERAL_STRING(ps, PROGRESS_STR);
+  return RemoveAddEventListener(ps, mOnProgressListener, aOnprogress);
+}
+
+nsresult
+nsXMLHttpRequestUpload::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
+{
+  aVisitor.mCanHandle = PR_TRUE;
+  aVisitor.mParentTarget = nsnull;
+  return NS_OK;
+}
+
+nsresult
+nsXMLHttpRequestUpload::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
+{
+  return NS_OK;
+}
+
+nsresult
+nsXMLHttpRequestUpload::DispatchDOMEvent(nsEvent* aEvent, nsIDOMEvent* aDOMEvent,
+                                         nsPresContext* aPresContext,
+                                         nsEventStatus* aEventStatus)
+{
+  return
+    nsEventDispatcher::DispatchDOMEvent(static_cast<nsPIDOMEventTarget*>(this),
+                                        aEvent, aDOMEvent, aPresContext,
+                                        aEventStatus);
+}
+
+nsresult
+nsXMLHttpRequestUpload::GetListenerManager(PRBool aCreateIfNotFound,
+                                           nsIEventListenerManager** aResult)
+{
+  if (!mListenerManager) {
+    if (!aCreateIfNotFound) {
+      *aResult = nsnull;
+      return NS_OK;
+    }
+    nsresult rv = NS_NewEventListenerManager(getter_AddRefs(mListenerManager));
+    NS_ENSURE_SUCCESS(rv, rv);
+    mListenerManager->SetListenerTarget(static_cast<nsPIDOMEventTarget*>(this));
+  }
+
+  NS_ADDREF(*aResult = mListenerManager);
+  return NS_OK;
+}
+
+nsresult
+nsXMLHttpRequestUpload::AddEventListenerByIID(nsIDOMEventListener *aListener,
+                                              const nsIID& aIID)
+{
+  nsCOMPtr<nsIEventListenerManager> elm;
+  GetListenerManager(PR_TRUE, getter_AddRefs(elm));
+  if (elm) {
+    elm->AddEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE);
+  }
+  return NS_OK;
+}
+
+nsresult
+nsXMLHttpRequestUpload::RemoveEventListenerByIID(nsIDOMEventListener *aListener,
+                                           const nsIID& aIID)
+{
+  nsCOMPtr<nsIEventListenerManager> elm;
+  GetListenerManager(PR_FALSE, getter_AddRefs(elm));
+  if (elm) {
+    return elm->RemoveEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE);
+  }
+  return NS_OK;
+}
+
+nsresult
+nsXMLHttpRequestUpload::GetSystemEventGroup(nsIDOMEventGroup** aGroup)
+{
+  nsCOMPtr<nsIEventListenerManager> elm;
+  nsresult rv = GetListenerManager(PR_TRUE, getter_AddRefs(elm));
+  if (elm) {
+    return elm->GetSystemEventGroupLM(aGroup);
+  }
+  return rv;
+}
+
+nsresult
+nsXMLHttpRequestUpload::GetContextForEventHandlers(nsIScriptContext** aContext)
+{
+  return mOwner->GetContextForEventHandlers(aContext);
 }
 
 /////////////////////////////////////////////
 //
 //
 /////////////////////////////////////////////
 
 nsXMLHttpRequest::nsXMLHttpRequest()
@@ -429,16 +719,19 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mListenerManager)
 
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mXMLParserStreamListener)
 
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mChannelEventSink)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mProgressEventSink)
 
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOwner)
+
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mUpload,
+                                                       nsIXMLHttpRequestUpload)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsXMLHttpRequest)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mContext)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mChannel)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mReadRequest)
 
@@ -451,16 +744,18 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ns
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mListenerManager)
 
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mXMLParserStreamListener)
 
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mChannelEventSink)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mProgressEventSink)
 
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOwner)
+
+  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mUpload)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 
 // QueryInterface implementation for nsXMLHttpRequest
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsXMLHttpRequest)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXMLHttpRequest)
   NS_INTERFACE_MAP_ENTRY(nsIXMLHttpRequest)
   NS_INTERFACE_MAP_ENTRY(nsIJSXMLHttpRequest)
@@ -992,20 +1287,16 @@ nsXMLHttpRequest::CreateEvent(const nsAS
   if (!privevent) {
     NS_IF_RELEASE(*aDOMEvent);
     return NS_ERROR_FAILURE;
   }
 
   if (!aType.IsEmpty()) {
     (*aDOMEvent)->InitEvent(aType, PR_FALSE, PR_FALSE);
   }
-  
-  privevent->SetTarget(this);
-  privevent->SetCurrentTarget(this);
-  privevent->SetOriginalTarget(this);
 
   // We assume anyone who managed to call CreateEvent is trusted
   privevent->SetTrusted(PR_TRUE);
 
   return NS_OK;
 }
 
 already_AddRefed<nsIHttpChannel>
@@ -1148,19 +1439,20 @@ nsXMLHttpRequest::OpenRequest(const nsAC
   nsCOMPtr<nsILoadGroup> loadGroup;
   GetLoadGroup(getter_AddRefs(loadGroup));
 
   // nsIRequest::LOAD_BACKGROUND prevents throbber from becoming active, which
   // in turn keeps STOP button from becoming active.  If the consumer passed in
   // a progress event handler we must load with nsIRequest::LOAD_NORMAL or
   // necko won't generate any progress notifications
   nsLoadFlags loadFlags;
-  if (mListenerManager &&
+  if ((mListenerManager &&
       (mListenerManager->HasListenersFor(NS_LITERAL_STRING(PROGRESS_STR)) ||
-       mListenerManager->HasListenersFor(NS_LITERAL_STRING(UPLOADPROGRESS_STR)))) {
+       mListenerManager->HasListenersFor(NS_LITERAL_STRING(UPLOADPROGRESS_STR)))) ||
+       (mUpload && mUpload->HasListenersFor(NS_LITERAL_STRING(PROGRESS_STR)))) {
     loadFlags = nsIRequest::LOAD_NORMAL;
   } else {
     loadFlags = nsIRequest::LOAD_BACKGROUND;
   }
   rv = NS_NewChannel(getter_AddRefs(mChannel), uri, nsnull, loadGroup, nsnull,
                      loadFlags);
   if (NS_FAILED(rv)) return rv;
 
@@ -2188,29 +2480,32 @@ nsXMLHttpRequest::OnChannelRedirect(nsIC
 //
 
 NS_IMETHODIMP
 nsXMLHttpRequest::OnProgress(nsIRequest *aRequest, nsISupports *aContext, PRUint64 aProgress, PRUint64 aProgressMax)
 {
   // We're uploading if our state is XML_HTTP_REQUEST_OPENED or
   // XML_HTTP_REQUEST_SENT
   nsCOMPtr<nsIDOMEvent> event;
-  nsresult rv = CreateEvent(((XML_HTTP_REQUEST_OPENED | XML_HTTP_REQUEST_SENT) & mState)
-                            ? NS_LITERAL_STRING(UPLOADPROGRESS_STR)
-                            : NS_LITERAL_STRING(PROGRESS_STR),
+  PRBool upload = !!((XML_HTTP_REQUEST_OPENED | XML_HTTP_REQUEST_SENT) & mState)
+  nsresult rv = CreateEvent(upload ? NS_LITERAL_STRING(UPLOADPROGRESS_STR)
+                                   : NS_LITERAL_STRING(PROGRESS_STR),
                             getter_AddRefs(event));
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsRefPtr<nsXMLHttpProgressEvent> progressEvent =
     new nsXMLHttpProgressEvent(event, aProgress, aProgressMax); 
   if (!progressEvent)
     return NS_ERROR_OUT_OF_MEMORY;
 
   event = progressEvent;
   DispatchDOMEvent(nsnull, event, nsnull, nsnull);
+  if (upload && mUpload) {
+    nsCOMPtr<nsI>
+  }
 
   if (mProgressEventSink) {
     mProgressEventSink->OnProgress(aRequest, aContext, aProgress,
                                    aProgressMax);
   }
 
   return NS_OK;
 }
@@ -2372,16 +2667,28 @@ nsXMLHttpRequest::GetSystemEventGroup(ns
 
 nsresult
 nsXMLHttpRequest::GetContextForEventHandlers(nsIScriptContext** aContext)
 {
   NS_IF_ADDREF(*aContext = mScriptContext);
   return NS_OK;
 }
 
+NS_IMETHODIMP
+nsXMLHttpRequest::GetUpload(nsIXMLHttpRequestUpload** aUpload)
+{
+  *aUpload = nsnull;
+  if (!mUpload) {
+    mUpload = new nsXMLHttpRequestUpload(this);
+    NS_ENSURE_TRUE(mUpload, NS_ERROR_OUT_OF_MEMORY);
+  }
+  NS_ADDREF(*aUpload = mUpload.get());
+  return NS_OK;
+}
+
 NS_IMPL_ISUPPORTS1(nsXMLHttpRequest::nsHeaderVisitor, nsIHttpHeaderVisitor)
 
 NS_IMETHODIMP nsXMLHttpRequest::
 nsHeaderVisitor::VisitHeader(const nsACString &header, const nsACString &value)
 {
     mHeaders.Append(header);
     mHeaders.Append(": ");
     mHeaders.Append(value);
diff --git a/content/base/src/nsXMLHttpRequest.h b/content/base/src/nsXMLHttpRequest.h
--- a/content/base/src/nsXMLHttpRequest.h
+++ b/content/base/src/nsXMLHttpRequest.h
@@ -63,16 +63,17 @@
 #include "nsCycleCollectionParticipant.h"
 #include "nsIJSNativeInitializer.h"
 #include "nsPIDOMWindow.h"
 #include "nsIDOMLSProgressEvent.h"
 #include "nsClassHashtable.h"
 #include "nsHashKeys.h"
 #include "prclist.h"
 #include "prtime.h"
+#include "nsIEventListenerManager.h"
 
 class nsILoadGroup;
 
 class nsDOMEventListenerWrapper : public nsIDOMEventListener
 {
 public:
   nsDOMEventListenerWrapper(nsIDOMEventListener* aListener)
   : mListener(aListener) {}
@@ -80,16 +81,66 @@ public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_CLASS(nsDOMEventListenerWrapper)
 
   NS_DECL_NSIDOMEVENTLISTENER
 
   nsIDOMEventListener* GetInner() { return mListener; }
 protected:
   nsCOMPtr<nsIDOMEventListener> mListener;
+};
+
+class nsXMLHttpRequestUpload : public nsIXMLHttpRequestUpload,
+                               public nsIDOMNSEventTarget,
+                               public nsPIDOMEventTarget
+{
+public:
+  nsXMLHttpRequestUpload(nsPIDOMEventTarget* aOwner) :
+    mOwner(aOwner), mLang(nsIProgrammingLanguage::JAVASCRIPT) {}
+  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+  NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsXMLHttpRequestUpload,
+                                           nsIXMLHttpRequestUpload)
+  NS_DECL_NSIXMLHTTPREQUESTEVENTTARGET
+  NS_DECL_NSIXMLHTTPREQUESTUPLOAD
+  NS_DECL_NSIDOMEVENTTARGET
+  NS_DECL_NSIDOMNSEVENTTARGET
+  // nsPIDOMEventTarget
+  virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor);
+  virtual nsresult PostHandleEvent(nsEventChainPostVisitor& aVisitor);
+  virtual nsresult DispatchDOMEvent(nsEvent* aEvent, nsIDOMEvent* aDOMEvent,
+                                    nsPresContext* aPresContext,
+                                    nsEventStatus* aEventStatus);
+  virtual nsresult GetListenerManager(PRBool aCreateIfNotFound,
+                                      nsIEventListenerManager** aResult);
+  virtual nsresult AddEventListenerByIID(nsIDOMEventListener *aListener,
+                                         const nsIID& aIID);
+  virtual nsresult RemoveEventListenerByIID(nsIDOMEventListener *aListener,
+                                            const nsIID& aIID);
+  virtual nsresult GetSystemEventGroup(nsIDOMEventGroup** aGroup);
+  virtual nsresult GetContextForEventHandlers(nsIScriptContext** aContext);
+
+  PRBool HasListenersFor(const nsAString& aType)
+  {
+    return mListenerManager && mListenerManager->HasListenersFor(aType);
+  }
+protected:
+  nsresult RemoveAddEventListener(const nsAString& aType,
+                                  nsRefPtr<nsDOMEventListenerWrapper>& aCurrent,
+                                  nsIDOMEventListener* aNew);
+
+  nsresult GetInnerEventListener(nsRefPtr<nsDOMEventListenerWrapper>& aWrapper,
+                                 nsIDOMEventListener** aListener);
+  nsCOMPtr<nsPIDOMEventTarget> mOwner;
+  nsRefPtr<nsDOMEventListenerWrapper> mOnLoadListener;
+  nsRefPtr<nsDOMEventListenerWrapper> mOnErrorListener;
+  nsRefPtr<nsDOMEventListenerWrapper> mOnAbortListener;
+  nsRefPtr<nsDOMEventListenerWrapper> mOnLoadStartListener;
+  nsRefPtr<nsDOMEventListenerWrapper> mOnProgressListener;
+  nsCOMPtr<nsIEventListenerManager> mListenerManager;
+  PRUint32 mLang;
 };
 
 class nsXMLHttpRequest : public nsIXMLHttpRequest,
                          public nsIJSXMLHttpRequest,
                          public nsIDOMLoadListener,
                          public nsIDOMEventTarget,
                          public nsIDOMNSEventTarget,
                          public nsPIDOMEventTarget,
@@ -269,18 +320,20 @@ protected:
   nsCOMPtr<nsIChannelEventSink> mChannelEventSink;
   nsCOMPtr<nsIProgressEventSink> mProgressEventSink;
 
   PRUint32 mState;
 
   // List of potentially dangerous headers explicitly set using
   // SetRequestHeader.
   nsTArray<nsCString> mExtraRequestHeaders;
+
+  nsRefPtr<nsXMLHttpRequestUpload> mUpload;
 };
-
+                                                    
 // helper class to expose a progress DOM Event
 
 class nsXMLHttpProgressEvent : public nsIDOMLSProgressEvent
 {
 public:
   nsXMLHttpProgressEvent(nsIDOMEvent * aInner, PRUint64 aCurrentProgress, PRUint64 aMaxProgress);
   virtual ~nsXMLHttpProgressEvent();
 
diff --git a/content/events/public/nsIPrivateDOMEvent.h b/content/events/public/nsIPrivateDOMEvent.h
--- a/content/events/public/nsIPrivateDOMEvent.h
+++ b/content/events/public/nsIPrivateDOMEvent.h
@@ -99,10 +99,11 @@ NS_NewDOMSVGZoomEvent(nsIDOMEvent** aRes
 NS_NewDOMSVGZoomEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, class nsGUIEvent* aEvent);
 #endif // MOZ_SVG
 nsresult
 NS_NewDOMXULCommandEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, class nsXULCommandEvent* aEvent);
 nsresult
 NS_NewDOMCommandEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, nsCommandEvent* aEvent);
 nsresult
 NS_NewDOMMessageEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, class nsEvent* aEvent);
-
+nsresult
+NS_NewDOMProgressEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, class nsEvent* aEvent);
 #endif // nsIPrivateDOMEvent_h__
diff --git a/content/events/src/Makefile.in b/content/events/src/Makefile.in
--- a/content/events/src/Makefile.in
+++ b/content/events/src/Makefile.in
@@ -77,16 +77,17 @@ CPPSRCS		= \
 		nsDOMMouseEvent.cpp \
 		nsDOMMutationEvent.cpp \
 		nsDOMPopupBlockedEvent.cpp \
 		nsDOMBeforeUnloadEvent.cpp \
 		nsDOMPageTransitionEvent.cpp \
 		nsDOMXULCommandEvent.cpp \
 		nsDOMCommandEvent.cpp \
 		nsDOMMessageEvent.cpp \
+		nsDOMProgressEvent.cpp \
 		nsPrivateTextRange.cpp \
 		nsDOMEventGroup.cpp \
 		nsXMLEventsManager.cpp \
 		nsXMLEventsElement.cpp \
 		nsPLDOMEvent.cpp \
 		nsEventDispatcher.cpp \
 		nsIMEStateManager.cpp \
 		nsQueryContentEventHandler.cpp \
diff --git a/content/events/src/nsEventDispatcher.cpp b/content/events/src/nsEventDispatcher.cpp
--- a/content/events/src/nsEventDispatcher.cpp
+++ b/content/events/src/nsEventDispatcher.cpp
@@ -648,11 +648,13 @@ nsEventDispatcher::CreateEvent(nsPresCon
   if (aEventType.LowerCaseEqualsLiteral("commandevent") ||
       aEventType.LowerCaseEqualsLiteral("commandevents"))
     return NS_NewDOMCommandEvent(aDOMEvent, aPresContext, nsnull);
   if (aEventType.LowerCaseEqualsLiteral("datacontainerevent") ||
       aEventType.LowerCaseEqualsLiteral("datacontainerevents"))
     return NS_NewDOMDataContainerEvent(aDOMEvent, aPresContext, nsnull);
   if (aEventType.LowerCaseEqualsLiteral("messageevent"))
     return NS_NewDOMMessageEvent(aDOMEvent, aPresContext, nsnull);
+  if (aEventType.LowerCaseEqualsLiteral("progressevent"))
+    return NS_NewDOMProgressEvent(aDOMEvent, aPresContext, nsnull);
 
   return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
 }
diff --git a/dom/public/idl/events/Makefile.in b/dom/public/idl/events/Makefile.in
--- a/dom/public/idl/events/Makefile.in
+++ b/dom/public/idl/events/Makefile.in
@@ -67,11 +67,12 @@ XPIDLSRCS =					\
 	nsIDOMNSUIEvent.idl			\
 	nsIDOMPopupBlockedEvent.idl		\
 	nsIDOMBeforeUnloadEvent.idl		\
 	nsIDOMNSEventTarget.idl			\
 	nsIDOMSmartCardEvent.idl                \
 	nsIDOMPageTransitionEvent.idl		\
 	nsIDOMCommandEvent.idl			\
 	nsIDOMMessageEvent.idl			\
+	nsIDOMProgressEvent.idl			\
 	$(NULL)
 
 include $(topsrcdir)/config/rules.mk
diff --git a/dom/public/nsDOMClassInfoID.h b/dom/public/nsDOMClassInfoID.h
--- a/dom/public/nsDOMClassInfoID.h
+++ b/dom/public/nsDOMClassInfoID.h
@@ -419,16 +419,20 @@ enum nsDOMClassInfoID {
 
   // Data Events
   eDOMClassInfo_DataContainerEvent_id,
 
   // event used for cross-domain message-passing and for server-sent events in
   // HTML5
   eDOMClassInfo_MessageEvent_id,
 
+  eDOMClassInfo_XMLHttpRequestUpload_id,
+
+  eDOMClassInfo_ProgressEvent_id,
+
   // This one better be the last one in this list
   eDOMClassInfoIDCount
 };
 
 /**
  * nsIClassInfo helper macros
  */
 
diff --git a/dom/src/base/nsDOMClassInfo.cpp b/dom/src/base/nsDOMClassInfo.cpp
--- a/dom/src/base/nsDOMClassInfo.cpp
+++ b/dom/src/base/nsDOMClassInfo.cpp
@@ -237,16 +237,17 @@
 #include "nsIDOMCommandEvent.h"
 #include "nsIDOMPopupBlockedEvent.h"
 #include "nsIDOMBeforeUnloadEvent.h"
 #include "nsIDOMMutationEvent.h"
 #include "nsIDOMSmartCardEvent.h"
 #include "nsIDOMXULCommandEvent.h"
 #include "nsIDOMPageTransitionEvent.h"
 #include "nsIDOMMessageEvent.h"
+#include "nsIDOMProgressEvent.h"
 #include "nsIDOMNSDocumentStyle.h"
 #include "nsIDOMDocumentRange.h"
 #include "nsIDOMDocumentTraversal.h"
 #include "nsIDOMDocumentXBL.h"
 #include "nsIDOMDocumentView.h"
 #include "nsIDOMElementCSSInlineStyle.h"
 #include "nsIDOMLinkStyle.h"
 #include "nsIDOMHTMLDocument.h"
@@ -1182,16 +1183,18 @@ static nsDOMClassInfoData sClassInfoData
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(XMLSerializer, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA(XMLHttpProgressEvent, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(XMLHttpRequest, nsEventTargetSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
+  NS_DEFINE_CLASSINFO_DATA(XMLHttpRequestUpload, nsEventTargetSH,
+                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA(ClientRect, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(ClientRectList, nsClientRectListSH,
                            ARRAY_SCRIPTABLE_FLAGS)
 
   // Define MOZ_SVG_FOREIGNOBJECT here so that when it gets switched on,
   // we preserve binary compatibility. New classes should be added
@@ -1227,16 +1230,19 @@ static nsDOMClassInfoData sClassInfoData
   NS_DEFINE_CLASSINFO_DATA(ModalContentWindow, nsWindowSH,
                            DEFAULT_SCRIPTABLE_FLAGS |
                            WINDOW_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA(DataContainerEvent, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA(MessageEvent, nsDOMGenericSH,
+                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
+
+  NS_DEFINE_CLASSINFO_DATA(ProgressEvent, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 };
 
 // Objects that shuld be constructable through |new Name();|
 struct nsContractIDMapData
 {
   PRInt32 mDOMClassInfoID;
   const char *mContractID;
@@ -3287,16 +3293,22 @@ nsDOMClassInfo::Init()
 
   DOM_CLASSINFO_MAP_BEGIN(XMLHttpRequest, nsIXMLHttpRequest)
     DOM_CLASSINFO_MAP_ENTRY(nsIXMLHttpRequest)
     DOM_CLASSINFO_MAP_ENTRY(nsIJSXMLHttpRequest)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)
     DOM_CLASSINFO_MAP_ENTRY(nsIInterfaceRequestor)
   DOM_CLASSINFO_MAP_END
 
+  DOM_CLASSINFO_MAP_BEGIN(XMLHttpRequestUpload, nsIXMLHttpRequestUpload)
+    DOM_CLASSINFO_MAP_ENTRY(nsIXMLHttpRequestEventTarget)
+    DOM_CLASSINFO_MAP_ENTRY(nsIXMLHttpRequestUpload)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)
+  DOM_CLASSINFO_MAP_END
+
   DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(XMLHttpProgressEvent, nsIDOMEvent)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMEvent)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMLSProgressEvent)
   DOM_CLASSINFO_MAP_END
 
 #if defined(MOZ_SVG) && defined(MOZ_SVG_FOREIGNOBJECT)
   DOM_CLASSINFO_MAP_BEGIN(SVGForeignObjectElement, nsIDOMSVGForeignObjectElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGForeignObjectElement)
@@ -3366,16 +3378,21 @@ nsDOMClassInfo::Init()
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(DataContainerEvent, nsIDOMDataContainerEvent)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMDataContainerEvent)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(MessageEvent, nsIDOMMessageEvent)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMMessageEvent)
+    DOM_CLASSINFO_EVENT_MAP_ENTRIES
+  DOM_CLASSINFO_MAP_END
+
+  DOM_CLASSINFO_MAP_BEGIN(ProgressEvent, nsIDOMProgressEvent)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMProgressEvent)
     DOM_CLASSINFO_EVENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
 #ifdef NS_DEBUG
   {
     PRUint32 i = NS_ARRAY_LENGTH(sClassInfoData);
 
     if (i != eDOMClassInfoIDCount) {
--- /dev/null	2008-06-05 11:51:05.389205708 +0300
+++ mozilla/content/events/src/nsDOMProgressEvent.h	2008-06-05 18:17:00.000000000 +0300
@@ -0,0 +1,68 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is 
+ * Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Olli Pettay <Olli.Pettay@helsinki.fi> (original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nsDOMProgressEvent_h__
+#define nsDOMProgressEvent_h__
+
+#include "nsIDOMProgressEvent.h"
+#include "nsDOMEvent.h"
+#include "nsCycleCollectionParticipant.h"
+
+class nsDOMProgressEvent : public nsIDOMProgressEvent,
+                           public nsDOMEvent
+{
+public:
+  nsDOMProgressEvent(nsPresContext* aPresContext, nsEvent* aEvent)
+    : nsDOMEvent(aPresContext, aEvent)
+  {
+  }
+
+  NS_DECL_ISUPPORTS_INHERITED
+
+  NS_DECL_NSIDOMPROGRESSEVENT
+
+  // Forward to base class
+  NS_FORWARD_TO_NSDOMEVENT
+
+private:
+  PRBool   mLengthComputable;
+  PRUint32 mLoaded;
+  PRUint32 mTotal;
+};
+
+#endif // nsDOMProgressEvent_h__
--- /dev/null	2008-06-05 11:51:05.389205708 +0300
+++ mozilla/content/events/src/nsDOMProgressEvent.cpp	2008-06-05 19:03:37.000000000 +0300
@@ -0,0 +1,110 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Olli Pettay <Olli.Pettay@helsinki.fi> (original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsDOMProgressEvent.h"
+#include "nsContentUtils.h"
+
+NS_INTERFACE_MAP_BEGIN(nsDOMProgressEvent)
+  NS_INTERFACE_MAP_ENTRY(nsIDOMProgressEvent)
+  NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(ProgressEvent)
+NS_INTERFACE_MAP_END_INHERITING(nsDOMEvent)
+
+NS_IMPL_ADDREF_INHERITED(nsDOMProgressEvent, nsDOMEvent)
+NS_IMPL_RELEASE_INHERITED(nsDOMProgressEvent, nsDOMEvent)
+
+NS_IMETHODIMP
+nsDOMProgressEvent::InitProgressEvent(const   nsAString& aType,
+                                      PRBool   aCanBubble,
+                                      PRBool   aCancelable,
+                                      PRBool   aLengthComputable,
+                                      PRUint32 aLoaded,
+                                      PRUint32 aTotal)
+{
+  nsresult rv = nsDOMEvent::InitEvent(aType, aCanBubble, aCancelable);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  mLengthComputable = aLengthComputable;
+  mLoaded = aLoaded;
+  mTotal = aTotal;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDOMProgressEvent::InitProgressEventNS(const    nsAString& aNamespaceURI,
+                                        const    nsAString& aType,
+                                        PRBool   aCanBubble,
+                                        PRBool   aCancelable,
+                                        PRBool   aLengthComputable,
+                                        PRUint32 aLoaded,
+                                        PRUint32 aTotal)
+{
+  return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsDOMProgressEvent::GetLengthComputable(PRBool* aComputable)
+{
+  *aComputable = mLengthComputable;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDOMProgressEvent::GetLoaded(PRUint32* aLoaded)
+{
+  *aLoaded = mLoaded;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDOMProgressEvent::GetTotal(PRUint32* aTotal)
+{
+  *aTotal = mTotal;
+  return NS_OK;
+}
+
+nsresult
+NS_NewDOMProgressEvent(nsIDOMEvent** aInstancePtrResult,
+                       nsPresContext* aPresContext,
+                       nsEvent* aEvent) 
+{
+  nsDOMProgressEvent* it = new nsDOMProgressEvent(aPresContext, aEvent);
+  if (nsnull == it)
+    return NS_ERROR_OUT_OF_MEMORY;
+
+  return CallQueryInterface(it, aInstancePtrResult);
+}
--- /dev/null	2008-06-05 11:51:05.389205708 +0300
+++ mozilla/dom/public/idl/events/nsIDOMProgressEvent.idl	2008-06-05 18:10:15.000000000 +0300
@@ -0,0 +1,61 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Olli Pettay <Olli.Pettay@helsinki.fi> (original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsIDOMEvent.idl"
+
+[scriptable, uuid(06072bf2-2644-4042-9103-edc06df66ccf)]
+interface nsIDOMProgressEvent : nsIDOMEvent
+{
+   readonly attribute boolean       lengthComputable;
+   readonly attribute unsigned long loaded;
+   readonly attribute unsigned long total;
+   void initProgressEvent(in DOMString     typeArg,
+                          in boolean       canBubbleArg,
+                          in boolean       cancelableArg,
+                          in boolean       lengthComputableArg,
+                          in unsigned long loadedArg,
+                          in unsigned long totalArg);
+   void initProgressEventNS(in DOMString     namespaceURI,
+                            in DOMString     typeArg,
+                            in boolean       canBubbleArg,
+                            in boolean       cancelableArg,
+                            in boolean       lengthComputableArg,
+                            in unsigned long loadedArg,
+                            in unsigned long totalArg);
+
+};
