Bug 1231100 - Get rid of nsIDOMFileReader - patch 1, r=sicking
authorAndrea Marchesini <amarchesini@mozilla.com>
Wed, 09 Dec 2015 15:52:15 -0500
changeset 297682 aa1fccef59946325e40a9330dfe302d0b3a3c7c2
parent 297681 6ff143ef49ebce4663092109c9e6affd3ec1aa17
child 297683 a22ade61487c77f74e09723224470ca3c8dac7e5
push id8824
push userraliiev@mozilla.com
push dateMon, 14 Dec 2015 20:18:56 +0000
treeherdermozilla-aurora@e2031358e2a6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssicking
bugs1231100
milestone45.0a1
Bug 1231100 - Get rid of nsIDOMFileReader - patch 1, r=sicking
b2g/components/LogCapture.jsm
browser/components/migration/MSMigrationUtils.jsm
devtools/server/actors/device.js
devtools/server/actors/webapps.js
dom/apps/ImportExport.jsm
dom/base/FileReader.cpp
dom/base/FileReader.h
dom/base/moz.build
dom/base/nsDOMClassInfo.cpp
dom/base/nsIDOMFileReader.idl
dom/base/test/test_ipc_messagemanager_blob.html
dom/indexedDB/test/test_message_manager_ipc.html
dom/indexedDB/test/unit/test_blob_file_backed.js
dom/indexedDB/test/unit/xpcshell-head-parent-process.js
dom/ipc/tests/test_blob_sliced_from_parent_process.html
dom/mobilemessage/gonk/MmsService.js
dom/webidl/FileReader.webidl
js/xpconnect/tests/mochitest/test_bug790732.html
layout/build/nsLayoutModule.cpp
toolkit/components/thumbnails/PageThumbs.jsm
toolkit/components/thumbnails/content/backgroundPageThumbsContent.js
toolkit/modules/PropertyListUtils.jsm
xpcom/reflect/xptinfo/ShimInterfaceInfo.cpp
--- a/b2g/components/LogCapture.jsm
+++ b/b2g/components/LogCapture.jsm
@@ -193,19 +193,17 @@ var LogCapture = {
    * Dumping screenshot, returning a Promise. Will be resolved with the content
    * as an ArrayBuffer.
    */
   getScreenshot: function() {
     let deferred = Promise.defer();
     try {
       this.ensureLoaded();
 
-      let fr = Cc["@mozilla.org/files/filereader;1"]
-                  .createInstance(Ci.nsIDOMFileReader);
-
+      let fr = new FileReader();
       fr.onload = function(evt) {
         deferred.resolve(new Uint8Array(evt.target.result));
       };
 
       fr.onerror = function(evt) {
         deferred.reject(evt);
       };
 
--- a/browser/components/migration/MSMigrationUtils.jsm
+++ b/browser/components/migration/MSMigrationUtils.jsm
@@ -540,18 +540,17 @@ Cookies.prototype = {
       this.ctypesKernelHelpers.finalize();
 
       aCallback(success);
     }).apply(this);
     cookiesGenerator.next();
   },
 
   _readCookieFile(aFile, aCallback) {
-    let fileReader = Cc["@mozilla.org/files/filereader;1"].
-                     createInstance(Ci.nsIDOMFileReader);
+    let fileReader = new FileReader();
     let onLoadEnd = () => {
       fileReader.removeEventListener("loadend", onLoadEnd, false);
 
       if (fileReader.readyState != fileReader.DONE) {
         Cu.reportError("Could not read cookie contents: " + fileReader.error);
         aCallback(false);
         return;
       }
--- a/devtools/server/actors/device.js
+++ b/devtools/server/actors/device.js
@@ -20,17 +20,16 @@ var DeviceActor = exports.DeviceActor = 
 
   getDescription: method(function() {
     return getSystemInfo();
   }, {request: {},response: { value: RetVal("json")}}),
 
   getWallpaper: method(function() {
     let deferred = promise.defer();
     getSetting("wallpaper.image").then((blob) => {
-      let FileReader = CC("@mozilla.org/files/filereader;1");
       let reader = new FileReader();
       let conn = this.conn;
       reader.addEventListener("load", function() {
         let str = new LongStringActor(conn, reader.result);
         deferred.resolve(str);
       });
       reader.addEventListener("error", function() {
         deferred.reject(reader.error);
--- a/devtools/server/actors/webapps.js
+++ b/devtools/server/actors/webapps.js
@@ -846,18 +846,17 @@ WebappsActor.prototype = {
         deferred.resolve({
           error: "noIcon",
           message: "The icon file '" + iconURL + "' doesn't exist"
         });
         return;
       }
 
       // Convert the blog to a base64 encoded data URI
-      let reader = Cc["@mozilla.org/files/filereader;1"]
-                     .createInstance(Ci.nsIDOMFileReader);
+      let reader = new FileReader();
       reader.onload = function () {
         deferred.resolve({
           url: reader.result
         });
       };
       reader.onerror = function () {
         deferred.resolve({
           error: reader.error.name,
--- a/dom/apps/ImportExport.jsm
+++ b/dom/apps/ImportExport.jsm
@@ -257,18 +257,17 @@ this.ImportExport = {
   },
 
   // Returns a promise that resolves to the temp file path.
   _writeBlobToTempFile: function(aBlob) {
     // Save the blob to a temp file.
     debug("_writeBlobToTempFile");
     let path;
     return new Promise((aResolve, aReject) => {
-      let reader = Cc['@mozilla.org/files/filereader;1']
-                     .createInstance(Ci.nsIDOMFileReader);
+      let reader = new FileReader();
       reader.onloadend = () => {
         path = OS.Path.join(OS.Constants.Path.tmpDir, "app-blob.zip");
         debug("onloadend path=" + path);
         OS.File.openUnique(path).then(obj => {
           path = obj.path;
           let file = obj.file;
           debug("openUnique path=" + path);
           return file.write(new Uint8Array(reader.result))
--- a/dom/base/FileReader.cpp
+++ b/dom/base/FileReader.cpp
@@ -65,194 +65,108 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(FileReader,
                                                DOMEventTargetHelper)
   NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mResultArrayBuffer)
 NS_IMPL_CYCLE_COLLECTION_TRACE_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(FileReader)
   NS_INTERFACE_MAP_ENTRY(nsITimerCallback)
   NS_INTERFACE_MAP_ENTRY(nsIInputStreamCallback)
-  NS_INTERFACE_MAP_ENTRY(nsIDOMFileReader)
   NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
 NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
 
 NS_IMPL_ADDREF_INHERITED(FileReader, DOMEventTargetHelper)
 NS_IMPL_RELEASE_INHERITED(FileReader, DOMEventTargetHelper)
 
-NS_IMPL_EVENT_HANDLER(FileReader, abort)
-NS_IMPL_EVENT_HANDLER(FileReader, error)
-NS_IMPL_EVENT_HANDLER(FileReader, progress)
-NS_IMPL_EVENT_HANDLER(FileReader, load)
-NS_IMPL_EVENT_HANDLER(FileReader, loadend)
-NS_IMPL_EVENT_HANDLER(FileReader, loadstart)
-
 void
 FileReader::RootResultArrayBuffer()
 {
   mozilla::HoldJSObjects(this);
 }
 
 //FileReader constructors/initializers
 
-FileReader::FileReader()
-  : mFileData(nullptr)
+FileReader::FileReader(nsPIDOMWindow* aWindow)
+  : DOMEventTargetHelper(aWindow)
+  , mFileData(nullptr)
   , mDataLen(0)
   , mDataFormat(FILE_AS_BINARY)
   , mResultArrayBuffer(nullptr)
   , mProgressEventWasDelayed(false)
   , mTimerIsActive(false)
-  , mReadyState(0)
+  , mReadyState(EMPTY)
   , mTotal(0)
   , mTransferred(0)
 {
   SetDOMStringToNull(mResult);
 }
 
 FileReader::~FileReader()
 {
   FreeFileData();
   mResultArrayBuffer = nullptr;
   DropJSObjects(this);
 }
 
-/**
- * This Init method is called from the factory constructor.
- */
-nsresult
-FileReader::Init()
-{
-  // Instead of grabbing some random global from the context stack,
-  // let's use the default one (junk scope) for now.
-  // We should move away from this Init...
-  BindToOwner(xpc::NativeGlobal(xpc::PrivilegedJunkScope()));
-  return NS_OK;
-}
-
 /* static */ already_AddRefed<FileReader>
 FileReader::Constructor(const GlobalObject& aGlobal, ErrorResult& aRv)
 {
-  RefPtr<FileReader> fileReader = new FileReader();
-
+  // The owner can be null when this object is used by chrome code.
   nsCOMPtr<nsPIDOMWindow> owner = do_QueryInterface(aGlobal.GetAsSupports());
-  if (!owner) {
-    NS_WARNING("Unexpected owner");
-    aRv.Throw(NS_ERROR_FAILURE);
-    return nullptr;
+  RefPtr<FileReader> fileReader = new FileReader(owner);
+
+  if (!owner && nsContentUtils::IsCallerChrome()) {
+    // Instead of grabbing some random global from the context stack,
+    // let's use the default one (junk scope) for now.
+    // We should move away from this Init...
+    fileReader->BindToOwner(xpc::NativeGlobal(xpc::PrivilegedJunkScope()));
   }
 
-  fileReader->BindToOwner(owner);
   return fileReader.forget();
 }
 
 // nsIInterfaceRequestor
 
 NS_IMETHODIMP
 FileReader::GetInterface(const nsIID & aIID, void **aResult)
 {
   return QueryInterface(aIID, aResult);
 }
 
-// nsIDOMFileReader
-
-NS_IMETHODIMP
-FileReader::GetReadyState(uint16_t *aReadyState)
-{
-  *aReadyState = ReadyState();
-  return NS_OK;
-}
-
 void
-FileReader::GetResult(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
+FileReader::GetResult(JSContext* aCx,
+                      JS::MutableHandle<JS::Value> aResult,
                       ErrorResult& aRv)
 {
-  aRv = GetResult(aCx, aResult);
-}
+  JS::Rooted<JS::Value> result(aCx);
 
-NS_IMETHODIMP
-FileReader::GetResult(JSContext* aCx, JS::MutableHandle<JS::Value> aResult)
-{
-  JS::Rooted<JS::Value> result(aCx);
   if (mDataFormat == FILE_AS_ARRAYBUFFER) {
-    if (mReadyState == nsIDOMFileReader::DONE && mResultArrayBuffer) {
+    if (mReadyState == DONE && mResultArrayBuffer) {
       result.setObject(*mResultArrayBuffer);
     } else {
       result.setNull();
     }
+
     if (!JS_WrapValue(aCx, &result)) {
-      return NS_ERROR_FAILURE;
+      aRv.Throw(NS_ERROR_FAILURE);
+      return;
     }
+
     aResult.set(result);
-    return NS_OK;
+    return;
   }
 
   nsString tmpResult = mResult;
   if (!xpc::StringToJsval(aCx, tmpResult, aResult)) {
-    return NS_ERROR_FAILURE;
+    aRv.Throw(NS_ERROR_FAILURE);
+    return;
   }
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-FileReader::GetError(nsISupports** aError)
-{
-  NS_IF_ADDREF(*aError = GetError());
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-FileReader::ReadAsArrayBuffer(nsIDOMBlob* aBlob, JSContext* aCx)
-{
-  NS_ENSURE_TRUE(aBlob, NS_ERROR_NULL_POINTER);
-  ErrorResult rv;
-  RefPtr<Blob> blob = static_cast<Blob*>(aBlob);
-  ReadAsArrayBuffer(aCx, *blob, rv);
-  return rv.StealNSResult();
-}
-
-NS_IMETHODIMP
-FileReader::ReadAsBinaryString(nsIDOMBlob* aBlob)
-{
-  NS_ENSURE_TRUE(aBlob, NS_ERROR_NULL_POINTER);
-  ErrorResult rv;
-  RefPtr<Blob> blob = static_cast<Blob*>(aBlob);
-  ReadAsBinaryString(*blob, rv);
-  return rv.StealNSResult();
 }
 
-NS_IMETHODIMP
-FileReader::ReadAsText(nsIDOMBlob* aBlob,
-                            const nsAString &aCharset)
-{
-  NS_ENSURE_TRUE(aBlob, NS_ERROR_NULL_POINTER);
-  ErrorResult rv;
-  RefPtr<Blob> blob = static_cast<Blob*>(aBlob);
-  ReadAsText(*blob, aCharset, rv);
-  return rv.StealNSResult();
-}
-
-NS_IMETHODIMP
-FileReader::ReadAsDataURL(nsIDOMBlob* aBlob)
-{
-  NS_ENSURE_TRUE(aBlob, NS_ERROR_NULL_POINTER);
-  ErrorResult rv;
-  RefPtr<Blob> blob = static_cast<Blob*>(aBlob);
-  ReadAsDataURL(*blob, rv);
-  return rv.StealNSResult();
-}
-
-NS_IMETHODIMP
-FileReader::Abort()
-{
-  ErrorResult rv;
-  Abort(rv);
-  return rv.StealNSResult();
-}
-
-static
-NS_METHOD
+static NS_IMETHODIMP
 ReadFuncBinaryString(nsIInputStream* in,
                      void* closure,
                      const char* fromRawSegment,
                      uint32_t toOffset,
                      uint32_t count,
                      uint32_t *writeCount)
 {
   char16_t* dest = static_cast<char16_t*>(closure) + toOffset;
@@ -385,81 +299,83 @@ FileReader::DoReadData(nsIAsyncInputStre
 
 void
 FileReader::ReadFileContent(Blob& aBlob,
                             const nsAString &aCharset,
                             eDataFormat aDataFormat,
                             ErrorResult& aRv)
 {
   //Implicit abort to clear any other activity going on
-  Abort();
+  ErrorResult error;
+  Abort(error);
+  error.SuppressException();
+
   mError = nullptr;
   SetDOMStringToNull(mResult);
   mTransferred = 0;
   mTotal = 0;
-  mReadyState = nsIDOMFileReader::EMPTY;
+  mReadyState = EMPTY;
   FreeFileData();
 
   mBlob = &aBlob;
   mDataFormat = aDataFormat;
   CopyUTF16toUTF8(aCharset, mCharset);
 
   nsresult rv;
-
   nsCOMPtr<nsIStreamTransportService> sts =
     do_GetService(kStreamTransportServiceCID, &rv);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     aRv.Throw(rv);
     return;
   }
 
   nsCOMPtr<nsIInputStream> stream;
   mBlob->GetInternalStream(getter_AddRefs(stream), aRv);
   if (NS_WARN_IF(aRv.Failed())) {
     return;
   }
 
   nsCOMPtr<nsITransport> transport;
-  rv = sts->CreateInputTransport(stream,
-                                 /* aStartOffset */ 0,
-                                 /* aReadLimit */ -1,
-                                 /* aCloseWhenDone */ true,
-                                 getter_AddRefs(transport));
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    aRv.Throw(rv);
+  aRv = sts->CreateInputTransport(stream,
+                                  /* aStartOffset */ 0,
+                                  /* aReadLimit */ -1,
+                                  /* aCloseWhenDone */ true,
+                                  getter_AddRefs(transport));
+  if (NS_WARN_IF(aRv.Failed())) {
     return;
   }
 
   nsCOMPtr<nsIInputStream> wrapper;
-  rv = transport->OpenInputStream(/* aFlags */ 0,
-                                  /* aSegmentSize */ 0,
-                                  /* aSegmentCount */ 0,
-                                  getter_AddRefs(wrapper));
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    aRv.Throw(rv);
+  aRv = transport->OpenInputStream(/* aFlags */ 0,
+                                   /* aSegmentSize */ 0,
+                                   /* aSegmentCount */ 0,
+                                   getter_AddRefs(wrapper));
+  if (NS_WARN_IF(aRv.Failed())) {
     return;
   }
 
   MOZ_ASSERT(!mAsyncStream);
   mAsyncStream = do_QueryInterface(wrapper);
   MOZ_ASSERT(mAsyncStream);
 
   mTotal = mBlob->GetSize(aRv);
   if (NS_WARN_IF(aRv.Failed())) {
     return;
   }
 
-  rv = DoAsyncWait(mAsyncStream);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    aRv.Throw(rv);
+  aRv = mAsyncStream->AsyncWait(this,
+                                /* aFlags*/ 0,
+                                /* aRequestedCount */ 0,
+                                NS_GetCurrentThread());
+  if (NS_WARN_IF(aRv.Failed())) {
     return;
   }
 
   //FileReader should be in loading state here
-  mReadyState = nsIDOMFileReader::LOADING;
+  mReadyState = LOADING;
   DispatchProgressEvent(NS_LITERAL_STRING(LOADSTART_STR));
 
   if (mDataFormat == FILE_AS_ARRAYBUFFER) {
     mFileData = js_pod_malloc<char>(mTotal);
     if (!mFileData) {
       NS_WARNING("Preallocation failed for ReadFileData");
       aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
     }
@@ -509,17 +425,17 @@ FileReader::GetAsText(Blob *aBlob,
 nsresult
 FileReader::GetAsDataURL(Blob *aBlob,
                          const char *aFileData,
                          uint32_t aDataLen,
                          nsAString& aResult)
 {
   aResult.AssignLiteral("data:");
 
-  nsString contentType;
+  nsAutoString contentType;
   aBlob->GetType(contentType);
   if (!contentType.IsEmpty()) {
     aResult.Append(contentType);
   } else {
     aResult.AppendLiteral("application/octet-stream");
   }
   aResult.AppendLiteral(";base64,");
 
@@ -625,29 +541,32 @@ FileReader::Notify(nsITimer* aTimer)
 
   return NS_OK;
 }
 
 // InputStreamCallback
 NS_IMETHODIMP
 FileReader::OnInputStreamReady(nsIAsyncInputStream* aStream)
 {
-  if (mReadyState != 1 || aStream != mAsyncStream) {
+  if (mReadyState != LOADING || aStream != mAsyncStream) {
     return NS_OK;
   }
 
   uint64_t aCount;
   nsresult rv = aStream->Available(&aCount);
 
   if (NS_SUCCEEDED(rv) && aCount) {
     rv = DoReadData(aStream, aCount);
   }
 
   if (NS_SUCCEEDED(rv)) {
-    rv = DoAsyncWait(aStream);
+    rv = aStream->AsyncWait(this,
+                            /* aFlags*/ 0,
+                            /* aRequestedCount */ 0,
+                            NS_GetCurrentThread());
   }
 
   if (NS_FAILED(rv) || !aCount) {
     if (rv == NS_BASE_STREAM_CLOSED) {
       rv = NS_OK;
     }
     return OnLoadEnd(rv);
   }
@@ -669,57 +588,48 @@ FileReader::OnInputStreamReady(nsIAsyncI
 
 nsresult
 FileReader::OnLoadEnd(nsresult aStatus)
 {
   // Cancel the progress event timer
   ClearProgressEventTimer();
 
   // FileReader must be in DONE stage after an operation
-  mReadyState = 2;
+  mReadyState = DONE;
 
-  nsString successEvent, termEvent;
+  nsAutoString successEvent, termEvent;
   nsresult rv = DoOnLoadEnd(aStatus, successEvent, termEvent);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Set the status field as appropriate
   if (NS_FAILED(aStatus)) {
     DispatchError(aStatus, termEvent);
     return NS_OK;
   }
 
   // Dispatch event to signify end of a successful operation
   DispatchProgressEvent(successEvent);
   DispatchProgressEvent(termEvent);
 
   return NS_OK;
 }
 
-nsresult
-FileReader::DoAsyncWait(nsIAsyncInputStream* aStream)
-{
-  return aStream->AsyncWait(this,
-                            /* aFlags*/ 0,
-                            /* aRequestedCount */ 0,
-                            NS_GetCurrentThread());
-}
-
 void
 FileReader::Abort(ErrorResult& aRv)
 {
-  if (mReadyState != 1) {
+  if (mReadyState != LOADING) {
     // XXX The spec doesn't say this
     aRv.Throw(NS_ERROR_DOM_FILE_ABORT_ERR);
     return;
   }
 
   ClearProgressEventTimer();
 
-  mReadyState = 2; // There are DONE constants on multiple interfaces,
-                   // but they all have value 2.
+  mReadyState = DONE;
+
   // XXX The spec doesn't say this
   mError = new DOMError(GetOwner(), NS_LITERAL_STRING("AbortError"));
 
   // Revert status and result attributes
   SetDOMStringToNull(mResult);
   mResultArrayBuffer = nullptr;
 
   mAsyncStream = nullptr;
--- a/dom/base/FileReader.h
+++ b/dom/base/FileReader.h
@@ -8,17 +8,16 @@
 #define mozilla_dom_FileReader_h
 
 #include "mozilla/Attributes.h"
 #include "mozilla/DOMEventTargetHelper.h"
 #include "mozilla/dom/DOMError.h"
 
 #include "nsCOMPtr.h"
 #include "nsIAsyncInputStream.h"
-#include "nsIDOMFileReader.h"
 #include "nsIStreamListener.h"
 #include "nsISupportsUtils.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsITimer.h"
 #include "nsJSUtils.h"
 #include "nsString.h"
 #include "nsTArray.h"
 #include "nsWeakReference.h"
@@ -29,39 +28,32 @@
 namespace mozilla {
 namespace dom {
 
 class Blob;
 
 extern const uint64_t kUnknownSize;
 
 class FileReader final : public DOMEventTargetHelper,
-                         public nsIDOMFileReader,
                          public nsIInterfaceRequestor,
                          public nsSupportsWeakReference,
                          public nsIInputStreamCallback,
                          public nsITimerCallback
 {
 public:
-  FileReader();
+  explicit FileReader(nsPIDOMWindow* aWindow);
 
   NS_DECL_ISUPPORTS_INHERITED
 
-  NS_DECL_NSIDOMFILEREADER
   NS_DECL_NSITIMERCALLBACK
   NS_DECL_NSIINPUTSTREAMCALLBACK
   NS_DECL_NSIINTERFACEREQUESTOR
 
-  NS_REALLY_FORWARD_NSIDOMEVENTTARGET(DOMEventTargetHelper)
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(FileReader, DOMEventTargetHelper)
 
-  nsPIDOMWindow* GetParentObject() const
-  {
-    return GetOwner();
-  }
   virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
 
   // WebIDL
   static already_AddRefed<FileReader>
   Constructor(const GlobalObject& aGlobal, ErrorResult& aRv);
   void ReadAsArrayBuffer(JSContext* aCx, Blob& aBlob, ErrorResult& aRv)
   {
     ReadFileContent(aBlob, EmptyString(), FILE_AS_ARRAYBUFFER, aRv);
@@ -76,17 +68,17 @@ public:
   {
     ReadFileContent(aBlob, EmptyString(), FILE_AS_DATAURL, aRv);
   }
 
   void Abort(ErrorResult& aRv);
 
   uint16_t ReadyState() const
   {
-    return mReadyState;
+    return static_cast<uint16_t>(mReadyState);
   }
 
   DOMError* GetError() const
   {
     return mError;
   }
 
   void GetResult(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
@@ -99,21 +91,26 @@ public:
   IMPL_EVENT_HANDLER(error)
   IMPL_EVENT_HANDLER(loadend)
 
   void ReadAsBinaryString(Blob& aBlob, ErrorResult& aRv)
   {
     ReadFileContent(aBlob, EmptyString(), FILE_AS_BINARY, aRv);
   }
 
-  nsresult Init();
-
 private:
   virtual ~FileReader();
 
+  // This must be in sync with dom/webidl/FileReader.webidl
+  enum eReadyState {
+    EMPTY = 0,
+    LOADING = 1,
+    DONE = 2
+  };
+
   enum eDataFormat {
     FILE_AS_ARRAYBUFFER,
     FILE_AS_BINARY,
     FILE_AS_TEXT,
     FILE_AS_DATAURL
   };
 
   void RootResultArrayBuffer();
@@ -123,17 +120,16 @@ private:
                        ErrorResult& aRv);
   nsresult GetAsText(Blob *aBlob, const nsACString &aCharset,
                      const char *aFileData, uint32_t aDataLen,
                      nsAString &aResult);
   nsresult GetAsDataURL(Blob *aBlob, const char *aFileData,
                         uint32_t aDataLen, nsAString &aResult);
 
   nsresult OnLoadEnd(nsresult aStatus);
-  nsresult DoAsyncWait(nsIAsyncInputStream* aStream);
 
   void StartProgressEventTimer();
   void ClearProgressEventTimer();
   void DispatchError(nsresult rv, nsAString& finalEvent);
   nsresult DispatchProgressEvent(const nsAString& aType);
 
   nsresult DoReadData(nsIAsyncInputStream* aStream, uint64_t aCount);
 
@@ -161,17 +157,17 @@ private:
   nsCOMPtr<nsITimer> mProgressNotifier;
   bool mProgressEventWasDelayed;
   bool mTimerIsActive;
 
   nsCOMPtr<nsIAsyncInputStream> mAsyncStream;
 
   RefPtr<DOMError> mError;
 
-  uint16_t mReadyState;
+  eReadyState mReadyState;
 
   uint64_t mTotal;
   uint64_t mTransferred;
 };
 
 } // dom namespace
 } // mozilla namespace
 
--- a/dom/base/moz.build
+++ b/dom/base/moz.build
@@ -11,17 +11,16 @@ XPIDL_SOURCES += [
     'nsIContentPolicy.idl',
     'nsIContentPolicyBase.idl',
     'nsIDocumentEncoder.idl',
     'nsIDOMBlob.idl',
     'nsIDOMDataChannel.idl',
     'nsIDOMDOMCursor.idl',
     'nsIDOMDOMRequest.idl',
     'nsIDOMFileList.idl',
-    'nsIDOMFileReader.idl',
     'nsIDOMFormData.idl',
     'nsIDOMParser.idl',
     'nsIDOMSerializer.idl',
     'nsIDroppedLinkHandler.idl',
     'nsIEntropyCollector.idl',
     'nsIFrameLoader.idl',
     'nsIImageLoadingContent.idl',
     'nsIMessageManager.idl',
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -2270,18 +2270,17 @@ struct InterfaceShimEntry {
   const char *geckoName;
   const char *domName;
 };
 
 // We add shims from Components.interfaces.nsIDOMFoo to window.Foo for each
 // interface that has interface constants that sites might be getting off
 // of Ci.
 const InterfaceShimEntry kInterfaceShimMap[] =
-{ { "nsIDOMFileReader", "FileReader" },
-  { "nsIXMLHttpRequest", "XMLHttpRequest" },
+{ { "nsIXMLHttpRequest", "XMLHttpRequest" },
   { "nsIDOMDOMException", "DOMException" },
   { "nsIDOMNode", "Node" },
   { "nsIDOMCSSPrimitiveValue", "CSSPrimitiveValue" },
   { "nsIDOMCSSRule", "CSSRule" },
   { "nsIDOMCSSValue", "CSSValue" },
   { "nsIDOMEvent", "Event" },
   { "nsIDOMNSEvent", "Event" },
   { "nsIDOMKeyEvent", "KeyEvent" },
deleted file mode 100644
--- a/dom/base/nsIDOMFileReader.idl
+++ /dev/null
@@ -1,47 +0,0 @@
-/* -*- 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 "nsIDOMEventTarget.idl"
-
-interface nsIDOMEventListener;
-interface nsIDOMBlob;
-
-[builtinclass, uuid(2f34c719-bc14-4546-9fb9-2bab75e56e45)]
-interface nsIDOMFileReader : nsIDOMEventTarget
-{
-  [implicit_jscontext]
-  void readAsArrayBuffer(in nsIDOMBlob filedata);
-  void readAsBinaryString(in nsIDOMBlob filedata);
-  void readAsText(in nsIDOMBlob filedata, [optional] in DOMString encoding);
-  void readAsDataURL(in nsIDOMBlob file);
-
-  void abort();
-
-  const unsigned short EMPTY = 0;
-  const unsigned short LOADING = 1;
-  const unsigned short DONE = 2;
-  readonly attribute unsigned short readyState;
-
-  [implicit_jscontext]
-  readonly attribute jsval result;
-
-  // This is a DOMError
-  readonly attribute nsISupports error;
-
-  [implicit_jscontext] attribute jsval onloadstart;
-  [implicit_jscontext] attribute jsval onprogress;
-  [implicit_jscontext] attribute jsval onload;
-  [implicit_jscontext] attribute jsval onabort;
-  [implicit_jscontext] attribute jsval onerror;
-  [implicit_jscontext] attribute jsval onloadend;
-};
-
-%{ C++
-#define NS_FILEREADER_CID                            \
-{0x06aa7c21, 0xfe05, 0x4cf2,                         \
-{0xb1, 0xc4, 0x0c, 0x71, 0x26, 0xa4, 0xf7, 0x13}}
-#define NS_FILEREADER_CONTRACTID \
-"@mozilla.org/files/filereader;1"
-%}
--- a/dom/base/test/test_ipc_messagemanager_blob.html
+++ b/dom/base/test/test_ipc_messagemanager_blob.html
@@ -21,19 +21,17 @@
       "use strict";
 
       addMessageListener("test:ipcClonedMessage", function(message) {
         if (!(message.json instanceof Components.interfaces.nsIDOMBlob)) {
           sendAsyncMessage(message.name, message.json);
           return;
         }
 
-        let reader =
-          Components.classes["@mozilla.org/files/filereader;1"]
-                    .createInstance(Components.interfaces.nsIDOMFileReader);
+        let reader = new FileReader();
         reader.addEventListener("load", function() {
           let response = reader.result == "this is a great success!" ?
                          message.json :
                          "error";
           sendAsyncMessage(message.name, response);
         });
         reader.readAsText(message.json);
       });
--- a/dom/indexedDB/test/test_message_manager_ipc.html
+++ b/dom/indexedDB/test/test_message_manager_ipc.html
@@ -45,21 +45,16 @@ function childFrameScript() {
     let diag = pass ? "" : "got " + a + ", expected " + b;
     ok(pass, name, diag);
   }
 
   function finish(result) {
     sendAsyncMessage(mmName, { op: "done", result: result });
   }
 
-  function createFileReader() {
-    return Cc["@mozilla.org/files/filereader;1"]
-             .createInstance(Ci.nsIDOMFileReader);
-  }
-
   function grabAndContinue(arg) {
     testGenerator.send(arg);
   }
 
   function errorHandler(event) {
     ok(false,
        event.target + " received error event: '" + event.target.error.name +
        "'");
@@ -73,33 +68,33 @@ function childFrameScript() {
     let blob = message.data;
 
     ok(blob instanceof Ci.nsIDOMBlob, "Message manager sent a blob");
     is(blob.size, blobText.length, "Blob has correct length");
     is(blob.type, blobType, "Blob has correct type");
 
     info("Reading blob");
 
-    let reader = createFileReader();
+    let reader = new FileReader();
     reader.addEventListener("load", grabAndContinue);
     reader.readAsText(blob);
 
     yield undefined;
 
     is(reader.result, blobText, "Blob has correct data");
 
     let slice = blob.slice(0, blobData[0].length, blobType);
 
     ok(slice instanceof Ci.nsIDOMBlob, "Slice returned a blob");
     is(slice.size, blobData[0].length, "Slice has correct length");
     is(slice.type, blobType, "Slice has correct type");
 
     info("Reading slice");
 
-    reader = createFileReader();
+    reader = new FileReader();
     reader.addEventListener("load", grabAndContinue);
     reader.readAsText(slice);
 
     yield undefined;
 
     is(reader.result, blobData[0], "Slice has correct data");
 
     info("Deleting database");
@@ -150,17 +145,17 @@ function childFrameScript() {
     blob = event.target.result;
 
     ok(blob instanceof Ci.nsIDOMBlob, "Database gave us a blob");
     is(blob.size, blobText.length, "Blob has correct length");
     is(blob.type, blobType, "Blob has correct type");
 
     info("Reading blob");
 
-    reader = createFileReader();
+    reader = new FileReader();
     reader.addEventListener("load", grabAndContinue);
     reader.readAsText(blob);
 
     yield undefined;
 
     is(reader.result, blobText, "Blob has correct data");
 
     info("Storing slice from message manager in database");
@@ -185,17 +180,17 @@ function childFrameScript() {
     slice = event.target.result;
 
     ok(slice instanceof Ci.nsIDOMBlob, "Database gave us a blob");
     is(slice.size, blobData[0].length, "Slice has correct length");
     is(slice.type, blobType, "Slice has correct type");
 
     info("Reading Slice");
 
-    reader = createFileReader();
+    reader = new FileReader();
     reader.addEventListener("load", grabAndContinue);
     reader.readAsText(slice);
 
     yield undefined;
 
     is(reader.result, blobData[0], "Slice has correct data");
 
     info("Sending blob and slice from database to message manager");
--- a/dom/indexedDB/test/unit/test_blob_file_backed.js
+++ b/dom/indexedDB/test/unit/test_blob_file_backed.js
@@ -2,21 +2,16 @@
  * Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 var disableWorkerTest = "This test uses SpecialPowers";
 
 var testGenerator = testSteps();
 
-function createFileReader() {
-  return SpecialPowers.Cc["@mozilla.org/files/filereader;1"]
-                      .createInstance(SpecialPowers.Ci.nsIDOMFileReader);
-}
-
 function testSteps()
 {
   const fileIOFlags = 0x02 | // PR_WRONLY
                       0x08 | // PR_CREATEFILE
                       0x20;  // PR_TRUNCATE
   const filePerms = 0664;
   const fileData = "abcdefghijklmnopqrstuvwxyz";
   const fileType = "text/plain";
@@ -43,17 +38,17 @@ function testSteps()
   outStream.write(fileData, fileData.length);
   outStream.close();
 
   let file = SpecialPowers.createDOMFile(testFile.path, { type: fileType });
   ok(file instanceof File, "Got a File object");
   is(file.size, fileData.length, "Correct size");
   is(file.type, fileType, "Correct type");
 
-  let fileReader = createFileReader();
+  let fileReader = new FileReader();
   fileReader.onload = grabEventAndContinueHandler;
   fileReader.readAsText(file);
 
   let event = yield undefined;
 
   is(fileReader.result, fileData, "Correct data");
 
   let request = indexedDB.open(databaseName, 1);
@@ -80,17 +75,17 @@ function testSteps()
   event = yield undefined;
 
   file = event.target.result;
 
   ok(file instanceof File, "Got a File object");
   is(file.size, fileData.length, "Correct size");
   is(file.type, fileType, "Correct type");
 
-  fileReader = createFileReader();
+  fileReader = new FileReader();
   fileReader.onload = grabEventAndContinueHandler;
   fileReader.readAsText(file);
 
   event = yield undefined;
 
   is(fileReader.result, fileData, "Correct data");
 
   finishTest();
--- a/dom/indexedDB/test/unit/xpcshell-head-parent-process.js
+++ b/dom/indexedDB/test/unit/xpcshell-head-parent-process.js
@@ -334,22 +334,16 @@ function getBlob(str)
   return new Blob([str], {type: "type/text"});
 }
 
 function getFile(name, type, str)
 {
   return new File([str], name, {type: type});
 }
 
-function getFileReader()
-{
-  return SpecialPowers.Cc["@mozilla.org/files/filereader;1"]
-                      .createInstance(SpecialPowers.Ci.nsIDOMFileReader);
-}
-
 function compareBuffers(buffer1, buffer2)
 {
   if (buffer1.byteLength != buffer2.byteLength) {
     return false;
   }
   let view1 = new Uint8Array(buffer1);
   let view2 = new Uint8Array(buffer2);
   for (let i = 0; i < buffer1.byteLength; i++) {
@@ -383,29 +377,29 @@ function verifyBlob(blob1, blob2)
   for (let i = 0; i < bufferCache.length; i++) {
     if (bufferCache[i].blob == blob2) {
       buffer2 = bufferCache[i].buffer;
       break;
     }
   }
 
   if (!buffer2) {
-    let reader = getFileReader();
+    let reader = new FileReader();
     reader.readAsArrayBuffer(blob2);
     reader.onload = function(event) {
       buffer2 = event.target.result;
       bufferCache.push({ blob: blob2, buffer: buffer2 });
       if (buffer1) {
         verifyBuffers(buffer1, buffer2);
         testGenerator.next();
       }
     }
   }
 
-  let reader = getFileReader();
+  let reader = new FileReader();
   reader.readAsArrayBuffer(blob1);
   reader.onload = function(event) {
     buffer1 = event.target.result;
     if (buffer2) {
       verifyBuffers(buffer1, buffer2);
       testGenerator.next();
     }
   }
--- a/dom/ipc/tests/test_blob_sliced_from_parent_process.html
+++ b/dom/ipc/tests/test_blob_sliced_from_parent_process.html
@@ -39,38 +39,33 @@ function childFrameScript() {
     let diag = pass ? "" : "got " + a + ", expected " + b;
     ok(pass, name, diag);
   }
 
   function finish(result) {
     sendAsyncMessage(messageName, { op: "done", result: result });
   }
 
-  function createFileReader() {
-    return Cc["@mozilla.org/files/filereader;1"]
-             .createInstance(Ci.nsIDOMFileReader);
-  }
-
   function grabAndContinue(arg) {
     testGenerator.send(arg);
   }
 
   function testSteps() {
     addMessageListener(messageName, grabAndContinue);
     let message = yield undefined;
 
     let blob = message.data;
 
     ok(blob instanceof Ci.nsIDOMBlob, "Received a Blob");
     is(blob.size, blobText.length, "Blob has correct length");
     is(blob.type, blobType, "Blob has correct type");
 
     info("Reading blob");
 
-    let reader = createFileReader();
+    let reader = new FileReader();
     reader.addEventListener("load", grabAndContinue);
     reader.readAsText(blob);
 
     yield undefined;
 
     is(reader.result, blobText, "Blob has correct data");
 
     let firstSliceStart = blobData[0].length + blobData[1].length;
@@ -79,17 +74,17 @@ function childFrameScript() {
     let slice = blob.slice(firstSliceStart, firstSliceEnd, blobType);
 
     ok(slice instanceof Ci.nsIDOMBlob, "Slice returned a Blob");
     is(slice.size, blobData[2].length, "Slice has correct length");
     is(slice.type, blobType, "Slice has correct type");
 
     info("Reading slice");
 
-    reader = createFileReader();
+    reader = new FileReader();
     reader.addEventListener("load", grabAndContinue);
     reader.readAsText(slice);
 
     yield undefined;
 
     is(reader.result, blobData[2], "Slice has correct data");
 
     let secondSliceStart = blobData[2].indexOf("a");
--- a/dom/mobilemessage/gonk/MmsService.js
+++ b/dom/mobilemessage/gonk/MmsService.js
@@ -1298,18 +1298,17 @@ SendTransaction.prototype = Object.creat
         if (!(aPart.content instanceof Blob)) {
           numPartsToLoad--;
           if (!numPartsToLoad) {
             callbackIfValid();
           }
           return;
         }
 
-        let fileReader = Cc["@mozilla.org/files/filereader;1"]
-                         .createInstance(Ci.nsIDOMFileReader);
+        let fileReader = new FileReader();
         fileReader.addEventListener("loadend", (aEvent) => {
           let arrayBuffer = aEvent.target.result;
           aPart.content = new Uint8Array(arrayBuffer);
           numPartsToLoad--;
           if (!numPartsToLoad) {
             callbackIfValid();
           }
         });
--- a/dom/webidl/FileReader.webidl
+++ b/dom/webidl/FileReader.webidl
@@ -5,17 +5,18 @@
  *
  * The origin of this IDL file is
  * http://dev.w3.org/2006/webapi/FileAPI/#dfn-filereader
  *
  * Copyright © 2013 W3C® (MIT, ERCIM, Keio, Beihang), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
-[Constructor]
+[Constructor,
+ Exposed=(Window,System)]
 interface FileReader : EventTarget {
   // async read methods
   [Throws]
   void readAsArrayBuffer(Blob blob);
   [Throws]
   void readAsText(Blob blob, optional DOMString label = "");
   [Throws]
   void readAsDataURL(Blob blob);
--- a/js/xpconnect/tests/mochitest/test_bug790732.html
+++ b/js/xpconnect/tests/mochitest/test_bug790732.html
@@ -15,17 +15,16 @@ https://bugzilla.mozilla.org/show_bug.cg
   var Ci = Components.interfaces;
   ok(Ci, "interfaces shim exists!");
   is(typeof Components.classes, 'undefined', "Shouldn't have a Cc");
 
   // Check each interface that we shim. We start by checking specific
   // constants for a couple of interfaces, and then once it's pretty clear that
   // it's working as intended we just check that the objects themselves are the
   // same.
-  is(Ci.nsIDOMFileReader.DONE, FileReader.DONE);
   is(Ci.nsIXMLHttpRequest.HEADERS_RECEIVED, XMLHttpRequest.HEADERS_RECEIVED);
   is(Ci.nsIDOMDOMException.DATA_CLONE_ERR, DOMException.DATA_CLONE_ERR);
   is(Ci.nsIDOMNode.DOCUMENT_NODE, Node.DOCUMENT_NODE);
   is(Ci.nsIDOMCSSPrimitiveValue.CSS_PX, CSSPrimitiveValue.CSS_PX);
   is(Ci.nsIDOMCSSRule.NAMESPACE_RULE, CSSRule.NAMESPACE_RULE);
   is(Ci.nsIDOMCSSValue.CSS_PRIMITIVE_VALUE, CSSValue.CSS_PRIMITIVE_VALUE);
   is(Ci.nsIDOMEvent.FOCUS, Event.FOCUS);
   is(Ci.nsIDOMNSEvent.CLICK, Event.CLICK);
--- a/layout/build/nsLayoutModule.cpp
+++ b/layout/build/nsLayoutModule.cpp
@@ -62,19 +62,16 @@
 
 #include "mozilla/dom/DOMParser.h"
 #include "nsDOMSerializer.h"
 #include "nsXMLHttpRequest.h"
 
 // view stuff
 #include "nsContentCreatorFunctions.h"
 
-// DOM includes
-#include "mozilla/dom/FileReader.h"
-
 #include "nsFormData.h"
 #include "nsHostObjectProtocolHandler.h"
 #include "nsHostObjectURI.h"
 #include "nsGlobalWindowCommands.h"
 #include "nsIControllerCommandTable.h"
 #include "nsJSProtocolHandler.h"
 #include "nsScriptNameSpaceManager.h"
 #include "nsIControllerContext.h"
@@ -296,17 +293,16 @@ using mozilla::gmp::GeckoMediaPluginServ
 already_AddRefed<nsIPresentationService> NS_CreatePresentationService();
 
 // Factory Constructor
 NS_GENERIC_FACTORY_CONSTRUCTOR(txMozillaXSLTProcessor)
 NS_GENERIC_FACTORY_CONSTRUCTOR(XPathEvaluator)
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(txNodeSetAdaptor, Init)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsDOMSerializer)
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsXMLHttpRequest, Init)
-NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(FileReader, Init)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsFormData)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsBlobProtocolHandler)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsMediaStreamProtocolHandler)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsMediaSourceProtocolHandler)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsFontTableProtocolHandler)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsHostObjectURI)
 NS_GENERIC_FACTORY_CONSTRUCTOR(DOMParser)
 NS_GENERIC_FACTORY_CONSTRUCTOR(Exception)
@@ -746,17 +742,16 @@ NS_DEFINE_NAMED_CID(NS_WINDOWCONTROLLER_
 NS_DEFINE_NAMED_CID(NS_PLUGINDOCLOADERFACTORY_CID);
 NS_DEFINE_NAMED_CID(NS_PLUGINDOCUMENT_CID);
 NS_DEFINE_NAMED_CID(NS_VIDEODOCUMENT_CID);
 NS_DEFINE_NAMED_CID(NS_STYLESHEETSERVICE_CID);
 NS_DEFINE_NAMED_CID(TRANSFORMIIX_XSLT_PROCESSOR_CID);
 NS_DEFINE_NAMED_CID(TRANSFORMIIX_XPATH_EVALUATOR_CID);
 NS_DEFINE_NAMED_CID(TRANSFORMIIX_NODESET_CID);
 NS_DEFINE_NAMED_CID(NS_XMLSERIALIZER_CID);
-NS_DEFINE_NAMED_CID(NS_FILEREADER_CID);
 NS_DEFINE_NAMED_CID(NS_FORMDATA_CID);
 NS_DEFINE_NAMED_CID(NS_BLOBPROTOCOLHANDLER_CID);
 NS_DEFINE_NAMED_CID(NS_MEDIASTREAMPROTOCOLHANDLER_CID);
 NS_DEFINE_NAMED_CID(NS_MEDIASOURCEPROTOCOLHANDLER_CID);
 NS_DEFINE_NAMED_CID(NS_FONTTABLEPROTOCOLHANDLER_CID);
 NS_DEFINE_NAMED_CID(NS_HOSTOBJECTURI_CID);
 NS_DEFINE_NAMED_CID(NS_XMLHTTPREQUEST_CID);
 NS_DEFINE_NAMED_CID(NS_DOMPARSER_CID);
@@ -1054,17 +1049,16 @@ static const mozilla::Module::CIDEntry k
   { &kNS_PLUGINDOCLOADERFACTORY_CID, false, nullptr, CreateContentDLF },
   { &kNS_PLUGINDOCUMENT_CID, false, nullptr, CreatePluginDocument },
   { &kNS_VIDEODOCUMENT_CID, false, nullptr, CreateVideoDocument },
   { &kNS_STYLESHEETSERVICE_CID, false, nullptr, nsStyleSheetServiceConstructor },
   { &kTRANSFORMIIX_XSLT_PROCESSOR_CID, false, nullptr, txMozillaXSLTProcessorConstructor },
   { &kTRANSFORMIIX_XPATH_EVALUATOR_CID, false, nullptr, XPathEvaluatorConstructor },
   { &kTRANSFORMIIX_NODESET_CID, false, nullptr, txNodeSetAdaptorConstructor },
   { &kNS_XMLSERIALIZER_CID, false, nullptr, nsDOMSerializerConstructor },
-  { &kNS_FILEREADER_CID, false, nullptr, FileReaderConstructor },
   { &kNS_FORMDATA_CID, false, nullptr, nsFormDataConstructor },
   { &kNS_BLOBPROTOCOLHANDLER_CID, false, nullptr, nsBlobProtocolHandlerConstructor },
   { &kNS_MEDIASTREAMPROTOCOLHANDLER_CID, false, nullptr, nsMediaStreamProtocolHandlerConstructor },
   { &kNS_MEDIASOURCEPROTOCOLHANDLER_CID, false, nullptr, nsMediaSourceProtocolHandlerConstructor },
   { &kNS_FONTTABLEPROTOCOLHANDLER_CID, false, nullptr, nsFontTableProtocolHandlerConstructor },
   { &kNS_HOSTOBJECTURI_CID, false, nullptr, nsHostObjectURIConstructor },
   { &kNS_XMLHTTPREQUEST_CID, false, nullptr, nsXMLHttpRequestConstructor },
   { &kNS_DOMPARSER_CID, false, nullptr, DOMParserConstructor },
@@ -1222,17 +1216,16 @@ static const mozilla::Module::ContractID
   { NS_JSPROTOCOLHANDLER_CONTRACTID, &kNS_JSPROTOCOLHANDLER_CID },
   { NS_WINDOWCONTROLLER_CONTRACTID, &kNS_WINDOWCONTROLLER_CID },
   { PLUGIN_DLF_CONTRACTID, &kNS_PLUGINDOCLOADERFACTORY_CID },
   { NS_STYLESHEETSERVICE_CONTRACTID, &kNS_STYLESHEETSERVICE_CID },
   { TRANSFORMIIX_XSLT_PROCESSOR_CONTRACTID, &kTRANSFORMIIX_XSLT_PROCESSOR_CID },
   { NS_XPATH_EVALUATOR_CONTRACTID, &kTRANSFORMIIX_XPATH_EVALUATOR_CID },
   { TRANSFORMIIX_NODESET_CONTRACTID, &kTRANSFORMIIX_NODESET_CID },
   { NS_XMLSERIALIZER_CONTRACTID, &kNS_XMLSERIALIZER_CID },
-  { NS_FILEREADER_CONTRACTID, &kNS_FILEREADER_CID },
   { NS_FORMDATA_CONTRACTID, &kNS_FORMDATA_CID },
   { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX BLOBURI_SCHEME, &kNS_BLOBPROTOCOLHANDLER_CID },
   { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX MEDIASTREAMURI_SCHEME, &kNS_MEDIASTREAMPROTOCOLHANDLER_CID },
   { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX MEDIASOURCEURI_SCHEME, &kNS_MEDIASOURCEPROTOCOLHANDLER_CID },
   { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX FONTTABLEURI_SCHEME, &kNS_FONTTABLEPROTOCOLHANDLER_CID },
   { NS_XMLHTTPREQUEST_CONTRACTID, &kNS_XMLHTTPREQUEST_CID },
   { NS_DOMPARSER_CONTRACTID, &kNS_DOMPARSER_CID },
   { XPC_EXCEPTION_CONTRACTID, &kNS_XPCEXCEPTION_CID },
--- a/toolkit/components/thumbnails/PageThumbs.jsm
+++ b/toolkit/components/thumbnails/PageThumbs.jsm
@@ -78,19 +78,19 @@ const TaskUtils = {
    * Read the bytes from a blob, asynchronously.
    *
    * @return {Promise}
    * @resolve {ArrayBuffer} In case of success, the bytes contained in the blob.
    * @reject {DOMError} In case of error, the underlying DOMError.
    */
   readBlob: function readBlob(blob) {
     let deferred = Promise.defer();
-    let reader = Cc["@mozilla.org/files/filereader;1"].createInstance(Ci.nsIDOMFileReader);
+    let reader = new FileReader();
     reader.onloadend = function onloadend() {
-      if (reader.readyState != Ci.nsIDOMFileReader.DONE) {
+      if (reader.readyState != FileReader.DONE) {
         deferred.reject(reader.error);
       } else {
         deferred.resolve(reader.result);
       }
     };
     reader.readAsArrayBuffer(blob);
     return deferred.promise;
   }
@@ -300,18 +300,17 @@ this.PageThumbs = {
       // Ignore events unrelated to our request
       if (aMsg.data.id != index) {
         return;
       }
 
       mm.removeMessageListener("Browser:Thumbnail:Response", thumbFunc);
       let imageBlob = aMsg.data.thumbnail;
       let doc = aBrowser.parentElement.ownerDocument;
-      let reader = Cc["@mozilla.org/files/filereader;1"].
-                   createInstance(Ci.nsIDOMFileReader);
+      let reader = new FileReader();
       reader.addEventListener("loadend", function() {
         let image = doc.createElementNS(PageThumbUtils.HTML_NAMESPACE, "img");
         image.onload = function () {
           let thumbnail = doc.createElementNS(PageThumbUtils.HTML_NAMESPACE, "canvas");
           thumbnail.width = image.naturalWidth;
           thumbnail.height = image.naturalHeight;
           let ctx = thumbnail.getContext("2d");
           ctx.drawImage(image, 0, 0);
--- a/toolkit/components/thumbnails/content/backgroundPageThumbsContent.js
+++ b/toolkit/components/thumbnails/content/backgroundPageThumbsContent.js
@@ -136,18 +136,17 @@ const backgroundPageThumbsContent = {
       capture.imageBlob = new Blob([blob]);
       // Load about:blank to finish the capture and wait for onStateChange.
       this._loadAboutBlank();
     });
   },
 
   _finishCurrentCapture: function () {
     let capture = this._currentCapture;
-    let fileReader = Cc["@mozilla.org/files/filereader;1"].
-                     createInstance(Ci.nsIDOMFileReader);
+    let fileReader = new FileReader();
     fileReader.onloadend = () => {
       sendAsyncMessage("BackgroundPageThumbs:didCapture", {
         id: capture.id,
         imageData: fileReader.result,
         finalURL: capture.finalURL,
         telemetry: {
           CAPTURE_PAGE_LOAD_TIME_MS: capture.pageLoadTime,
           CAPTURE_CANVAS_DRAW_TIME_MS: capture.canvasDrawTime,
--- a/toolkit/modules/PropertyListUtils.jsm
+++ b/toolkit/modules/PropertyListUtils.jsm
@@ -95,18 +95,17 @@ this.PropertyListUtils = Object.freeze({
       try {
         if (file instanceof Ci.nsILocalFile) {
           if (!file.exists())
             throw new Error("The file pointed by aFile does not exist");
 
           file = new File(file);
         }
 
-        let fileReader = Cc["@mozilla.org/files/filereader;1"].
-                         createInstance(Ci.nsIDOMFileReader);
+        let fileReader = new FileReader();
         let onLoadEnd = function() {
           let root = null;
           try {
             fileReader.removeEventListener("loadend", onLoadEnd, false);
             if (fileReader.readyState != fileReader.DONE)
               throw new Error("Could not read file contents: " + fileReader.error);
 
             root = this._readFromArrayBufferSync(fileReader.result);
--- a/xpcom/reflect/xptinfo/ShimInterfaceInfo.cpp
+++ b/xpcom/reflect/xptinfo/ShimInterfaceInfo.cpp
@@ -39,17 +39,16 @@
 #include "nsIDOMDocumentFragment.h"
 #include "nsIDOMDocumentType.h"
 #include "nsIDOMDocumentXBL.h"
 #include "nsIDOMDragEvent.h"
 #include "nsIDOMElement.h"
 #include "nsIDOMEvent.h"
 #include "nsIDOMEventTarget.h"
 #include "nsIDOMFileList.h"
-#include "nsIDOMFileReader.h"
 #include "nsIDOMFocusEvent.h"
 #include "nsIDOMFormData.h"
 #include "nsIDOMGeoPositionError.h"
 #include "nsIDOMHistory.h"
 #include "nsIDOMHTMLAnchorElement.h"
 #include "nsIDOMHTMLAppletElement.h"
 #include "nsIDOMHTMLAreaElement.h"
 #include "nsIDOMHTMLBaseElement.h"
@@ -174,17 +173,16 @@
 #include "mozilla/dom/DocumentFragmentBinding.h"
 #include "mozilla/dom/DocumentTypeBinding.h"
 #include "mozilla/dom/DocumentBinding.h"
 #include "mozilla/dom/DragEventBinding.h"
 #include "mozilla/dom/ElementBinding.h"
 #include "mozilla/dom/EventBinding.h"
 #include "mozilla/dom/EventTargetBinding.h"
 #include "mozilla/dom/FileListBinding.h"
-#include "mozilla/dom/FileReaderBinding.h"
 #include "mozilla/dom/FocusEventBinding.h"
 #include "mozilla/dom/FormDataBinding.h"
 #include "mozilla/dom/HistoryBinding.h"
 #include "mozilla/dom/HTMLAnchorElementBinding.h"
 #include "mozilla/dom/HTMLAppletElementBinding.h"
 #include "mozilla/dom/HTMLAreaElementBinding.h"
 #include "mozilla/dom/HTMLBaseElementBinding.h"
 #include "mozilla/dom/HTMLBodyElementBinding.h"
@@ -363,17 +361,16 @@ const ComponentsInterfaceShimEntry kComp
   DEFINE_SHIM(Document),
   DEFINE_SHIM(DocumentFragment),
   DEFINE_SHIM(DocumentType),
   DEFINE_SHIM_WITH_CUSTOM_INTERFACE(nsIDOMDocumentXBL, Document),
   DEFINE_SHIM(DragEvent),
   DEFINE_SHIM(Element),
   DEFINE_SHIM(Event),
   DEFINE_SHIM(EventTarget),
-  DEFINE_SHIM(FileReader),
   DEFINE_SHIM(FileList),
   DEFINE_SHIM(FocusEvent),
   DEFINE_SHIM(FormData),
   DEFINE_SHIM_WITH_CUSTOM_INTERFACE(nsIDOMGeoPositionError, PositionError),
   DEFINE_SHIM(History),
   DEFINE_SHIM(HTMLAnchorElement),
   DEFINE_SHIM(HTMLAppletElement),
   DEFINE_SHIM(HTMLAreaElement),