Bug 811615 - Enable chrome code to create a new File object by wrapping an existing Blob and provide a custom name/type. r=sicking, a=akeybl
authorKyle Huey <khuey@kylehuey.com>
Tue, 11 Dec 2012 13:21:03 -0800
changeset 118842 2bbaa47b999ea92827111c2bcb4b62cf144e23b4
parent 118841 c0ed4a465b7afd4dc251a53a64d850d4af486235
child 118843 a649b71bf53109019e310cdacfa7ca8b7bca8488
push id2961
push userryanvm@gmail.com
push dateFri, 14 Dec 2012 03:05:01 +0000
treeherdermozilla-aurora@d0a8a8173ef1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssicking, akeybl
bugs811615
milestone19.0a2
Bug 811615 - Enable chrome code to create a new File object by wrapping an existing Blob and provide a custom name/type. r=sicking, a=akeybl
content/base/public/nsDOMFile.h
content/base/src/nsDOMBlobBuilder.cpp
content/base/src/nsDOMBlobBuilder.h
content/base/src/nsDOMFile.cpp
dom/base/nsDOMClassInfo.cpp
dom/base/nsDOMWindowUtils.cpp
dom/webidl/File.webidl
dom/webidl/WebIDL.mk
dom/workers/File.cpp
js/xpconnect/loader/Makefile.in
js/xpconnect/loader/mozJSComponentLoader.cpp
js/xpconnect/tests/unit/component-file.js
--- a/content/base/public/nsDOMFile.h
+++ b/content/base/public/nsDOMFile.h
@@ -196,18 +196,17 @@ public:
   : nsDOMFileBase(aContentType, aStart, aLength)
   { }
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
 
   NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsDOMFileCC, nsIDOMFile)
 };
 
-class nsDOMFileFile : public nsDOMFile,
-                      public nsIJSNativeInitializer
+class nsDOMFileFile : public nsDOMFile
 {
 public:
   // Create as a file
   nsDOMFileFile(nsIFile *aFile)
     : nsDOMFile(EmptyString(), EmptyString(), UINT64_MAX, UINT64_MAX),
       mFile(aFile), mWholeFile(true), mStoredFile(false)
   {
     NS_ASSERTION(mFile, "must have file");
@@ -292,37 +291,24 @@ public:
     : nsDOMFile(EmptyString(), EmptyString(), UINT64_MAX, UINT64_MAX),
       mWholeFile(true), mStoredFile(false)
   {
     // Lazily get the content type and size
     mContentType.SetIsVoid(true);
     mName.SetIsVoid(true);
   }
 
-  NS_DECL_ISUPPORTS_INHERITED
-
-  // nsIJSNativeInitializer
-  NS_IMETHOD Initialize(nsISupports* aOwner,
-                        JSContext* aCx,
-                        JSObject* aObj,
-                        uint32_t aArgc,
-                        jsval* aArgv);
-
   // Overrides
   NS_IMETHOD GetSize(uint64_t* aSize);
   NS_IMETHOD GetType(nsAString& aType);
   NS_IMETHOD GetLastModifiedDate(JSContext* cx, JS::Value* aLastModifiedDate);
   NS_IMETHOD GetMozLastModifiedDate(uint64_t* aLastModifiedDate);
   NS_IMETHOD GetMozFullPathInternal(nsAString& aFullPath);
   NS_IMETHOD GetInternalStream(nsIInputStream**);
 
-  // DOMClassInfo constructor (for File("foo"))
-  static nsresult
-  NewFile(nsISupports* *aNewObject);
-
 protected:
   // Create slice
   nsDOMFileFile(const nsDOMFileFile* aOther, uint64_t aStart, uint64_t aLength,
                 const nsAString& aContentType)
     : nsDOMFile(aContentType, aOther->mStart + aStart, aLength),
       mFile(aOther->mFile), mWholeFile(false),
       mStoredFile(aOther->mStoredFile), mCacheToken(aOther->mCacheToken)
   {
--- a/content/base/src/nsDOMBlobBuilder.cpp
+++ b/content/base/src/nsDOMBlobBuilder.cpp
@@ -1,16 +1,17 @@
 /* -*- 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 "nsDOMBlobBuilder.h"
 #include "jsfriendapi.h"
 #include "mozilla/dom/BlobBinding.h"
+#include "mozilla/dom/FileBinding.h"
 #include "nsAutoPtr.h"
 #include "nsDOMClassInfoID.h"
 #include "nsIMultiplexInputStream.h"
 #include "nsStringStream.h"
 #include "nsTArray.h"
 #include "nsJSUtils.h"
 #include "nsContentUtils.h"
 #include "nsIScriptError.h"
@@ -166,24 +167,27 @@ GetXPConnectNative(JSContext* aCx, JSObj
 
 NS_IMETHODIMP
 nsDOMMultipartFile::Initialize(nsISupports* aOwner,
                                JSContext* aCx,
                                JSObject* aObj,
                                uint32_t aArgc,
                                jsval* aArgv)
 {
-  return InitInternal(aCx, aArgc, aArgv, GetXPConnectNative);
+  if (!mIsFile) {
+    return InitBlob(aCx, aArgc, aArgv, GetXPConnectNative);
+  }
+  return InitFile(aCx, aArgc, aArgv);
 }
 
 nsresult
-nsDOMMultipartFile::InitInternal(JSContext* aCx,
-                                 uint32_t aArgc,
-                                 jsval* aArgv,
-                                 UnwrapFuncPtr aUnwrapFunc)
+nsDOMMultipartFile::InitBlob(JSContext* aCx,
+                             uint32_t aArgc,
+                             jsval* aArgv,
+                             UnwrapFuncPtr aUnwrapFunc)
 {
   bool nativeEOL = false;
   if (aArgc > 1) {
     if (NS_IsMainThread()) {
       BlobPropertyBag d;
       if (!d.Init(aCx, nullptr, aArgv[1])) {
         return NS_ERROR_TYPE_ERR;
       }
@@ -256,16 +260,110 @@ nsDOMMultipartFile::InitInternal(JSConte
 
     mBlobs = blobSet.GetBlobs();
   }
 
   return NS_OK;
 }
 
 nsresult
+nsDOMMultipartFile::InitFile(JSContext* aCx,
+                             uint32_t aArgc,
+                             jsval* aArgv)
+{
+  nsresult rv;
+
+  NS_ASSERTION(!mImmutable, "Something went wrong ...");
+  NS_ENSURE_TRUE(!mImmutable, NS_ERROR_UNEXPECTED);
+
+  if (!nsContentUtils::IsCallerChrome()) {
+    return NS_ERROR_DOM_SECURITY_ERR; // Real short trip
+  }
+
+  NS_ENSURE_TRUE(aArgc > 0, NS_ERROR_UNEXPECTED);
+
+  bool nativeEOL = false;
+  if (aArgc > 1) {
+    FilePropertyBag d;
+    if (!d.Init(aCx, nullptr, aArgv[1])) {
+      return NS_ERROR_TYPE_ERR;
+    }
+    mName = d.name;
+    mContentType = d.type;
+    nativeEOL = d.endings == EndingTypesValues::Native;
+  }
+
+  // We expect to get a path to represent as a File object,
+  // an nsIFile, or an nsIDOMFile.
+  nsCOMPtr<nsIFile> file;
+  nsCOMPtr<nsIDOMFile> domFile;
+  if (!aArgv[0].isString()) {
+    // Lets see if it's an nsIFile
+    if (!aArgv[0].isObject()) {
+      return NS_ERROR_UNEXPECTED; // We're not interested
+    }
+
+    JSObject* obj = &aArgv[0].toObject();
+
+    nsISupports* supports =
+      nsContentUtils::XPConnect()->GetNativeOfWrapper(aCx, obj);
+    if (!supports) {
+      return NS_ERROR_UNEXPECTED;
+    }
+
+    domFile = do_QueryInterface(supports);
+    file = do_QueryInterface(supports);
+    if (!domFile && !file) {
+      return NS_ERROR_UNEXPECTED;
+    }
+  } else {
+    // It's a string
+    JSString* str = JS_ValueToString(aCx, aArgv[0]);
+    NS_ENSURE_TRUE(str, NS_ERROR_XPC_BAD_CONVERT_JS);
+
+    nsDependentJSString xpcomStr;
+    if (!xpcomStr.init(aCx, str)) {
+      return NS_ERROR_XPC_BAD_CONVERT_JS;
+    }
+
+    rv = NS_NewLocalFile(xpcomStr, false, getter_AddRefs(file));
+    NS_ENSURE_SUCCESS(rv, rv);
+  }
+
+  if (file) {
+    bool exists;
+    rv = file->Exists(&exists);
+    NS_ENSURE_SUCCESS(rv, rv);
+    NS_ENSURE_TRUE(exists, NS_ERROR_FILE_NOT_FOUND);
+
+    bool isDir;
+    rv = file->IsDirectory(&isDir);
+    NS_ENSURE_SUCCESS(rv, rv);
+    NS_ENSURE_FALSE(isDir, NS_ERROR_FILE_IS_DIRECTORY);
+
+    if (mName.IsEmpty()) {
+      file->GetLeafName(mName);
+    }
+
+    domFile = new nsDOMFileFile(file);
+  }
+  
+  // XXXkhuey this is terrible
+  if (mContentType.IsEmpty()) {
+    domFile->GetType(mContentType);
+  }
+
+  BlobSet blobSet;
+  blobSet.AppendBlob(domFile);
+  mBlobs = blobSet.GetBlobs();
+
+  return NS_OK;
+}
+
+nsresult
 BlobSet::AppendVoidPtr(const void* aData, uint32_t aLength)
 {
   NS_ENSURE_ARG_POINTER(aData);
 
   uint64_t offset = mDataLen;
 
   if (!ExpandBufferSize(aLength))
     return NS_ERROR_OUT_OF_MEMORY;
--- a/content/base/src/nsDOMBlobBuilder.h
+++ b/content/base/src/nsDOMBlobBuilder.h
@@ -49,34 +49,47 @@ public:
   // nsIJSNativeInitializer
   NS_IMETHOD Initialize(nsISupports* aOwner,
                         JSContext* aCx,
                         JSObject* aObj,
                         uint32_t aArgc,
                         jsval* aArgv);
 
   typedef nsIDOMBlob* (*UnwrapFuncPtr)(JSContext*, JSObject*);
-  nsresult InitInternal(JSContext* aCx,
-                        uint32_t aArgc,
-                        jsval* aArgv,
-                        UnwrapFuncPtr aUnwrapFunc);
+  nsresult InitBlob(JSContext* aCx,
+                    uint32_t aArgc,
+                    jsval* aArgv,
+                    UnwrapFuncPtr aUnwrapFunc);
+  nsresult InitFile(JSContext* aCx,
+                    uint32_t aArgc,
+                    jsval* aArgv);
 
   already_AddRefed<nsIDOMBlob>
   CreateSlice(uint64_t aStart, uint64_t aLength, const nsAString& aContentType);
 
   NS_IMETHOD GetSize(uint64_t*);
   NS_IMETHOD GetInternalStream(nsIInputStream**);
 
   static nsresult
   NewFile(const nsAString& aName, nsISupports* *aNewObject);
 
   // DOMClassInfo constructor (for Blob([b1, "foo"], { type: "image/png" }))
   static nsresult
   NewBlob(nsISupports* *aNewObject);
 
+  // DOMClassInfo constructor (for File([b1, "foo"], { type: "image/png",
+  //                                                   name: "foo.png" }))
+  inline static nsresult
+  NewFile(nsISupports* *aNewObject)
+  {
+    // Initialization will set the filename, so we can pass in an empty string
+    // for now.
+    return NewFile(EmptyString(), aNewObject);
+  }
+
   virtual const nsTArray<nsCOMPtr<nsIDOMBlob> >*
   GetSubBlobs() const { return &mBlobs; }
 
 protected:
   nsTArray<nsCOMPtr<nsIDOMBlob> > mBlobs;
 };
 
 class BlobSet {
--- a/content/base/src/nsDOMFile.cpp
+++ b/content/base/src/nsDOMFile.cpp
@@ -465,35 +465,24 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsDOMFileCC)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsDOMFileCC)
 
 ////////////////////////////////////////////////////////////////////////////
 // nsDOMFileFile implementation
 
-NS_IMPL_ISUPPORTS_INHERITED1(nsDOMFileFile, nsDOMFile,
-                             nsIJSNativeInitializer)
-
 already_AddRefed<nsIDOMBlob>
 nsDOMFileFile::CreateSlice(uint64_t aStart, uint64_t aLength,
                            const nsAString& aContentType)
 {
   nsCOMPtr<nsIDOMBlob> t = new nsDOMFileFile(this, aStart, aLength, aContentType);
   return t.forget();
 }
 
-/* static */ nsresult
-nsDOMFileFile::NewFile(nsISupports* *aNewObject)
-{
-  nsCOMPtr<nsISupports> file = do_QueryObject(new nsDOMFileFile());
-  file.forget(aNewObject);
-  return NS_OK;
-}
-
 NS_IMETHODIMP
 nsDOMFileFile::GetMozFullPathInternal(nsAString &aFilename)
 {
   NS_ASSERTION(mIsFile, "Should only be called on files");
   return mFile->GetPath(aFilename);
 }
 
 NS_IMETHODIMP
@@ -588,81 +577,16 @@ NS_IMETHODIMP
 nsDOMFileFile::GetInternalStream(nsIInputStream **aStream)
 {
   return mWholeFile ?
     NS_NewLocalFileInputStream(aStream, mFile, -1, -1, sFileStreamFlags) :
     NS_NewPartialLocalFileInputStream(aStream, mFile, mStart, mLength,
                                       -1, -1, sFileStreamFlags);
 }
 
-NS_IMETHODIMP
-nsDOMFileFile::Initialize(nsISupports* aOwner,
-                          JSContext* aCx,
-                          JSObject* aObj,
-                          uint32_t aArgc,
-                          JS::Value* aArgv)
-{
-  nsresult rv;
-
-  NS_ASSERTION(!mImmutable, "Something went wrong ...");
-  NS_ENSURE_TRUE(!mImmutable, NS_ERROR_UNEXPECTED);
-
-  if (!nsContentUtils::IsCallerChrome()) {
-    return NS_ERROR_DOM_SECURITY_ERR; // Real short trip
-  }
-
-  NS_ENSURE_TRUE(aArgc > 0, NS_ERROR_UNEXPECTED);
-
-  // We expect to get a path to represent as a File object,
-  // or an nsIFile
-  nsCOMPtr<nsIFile> file;
-  if (!aArgv[0].isString()) {
-    // Lets see if it's an nsIFile
-    if (!aArgv[0].isObject()) {
-      return NS_ERROR_UNEXPECTED; // We're not interested
-    }
-
-    JSObject* obj = &aArgv[0].toObject();
-
-    // Is it an nsIFile
-    file = do_QueryInterface(
-      nsContentUtils::XPConnect()->
-        GetNativeOfWrapper(aCx, obj));
-    if (!file)
-      return NS_ERROR_UNEXPECTED;
-  } else {
-    // It's a string
-    JSString* str = JS_ValueToString(aCx, aArgv[0]);
-    NS_ENSURE_TRUE(str, NS_ERROR_XPC_BAD_CONVERT_JS);
-
-    nsDependentJSString xpcomStr;
-    if (!xpcomStr.init(aCx, str)) {
-      return NS_ERROR_XPC_BAD_CONVERT_JS;
-    }
-
-    rv = NS_NewLocalFile(xpcomStr, false, getter_AddRefs(file));
-    NS_ENSURE_SUCCESS(rv, rv);
-  }
-
-  bool exists;
-  rv = file->Exists(&exists);
-  NS_ENSURE_SUCCESS(rv, rv);
-  NS_ENSURE_TRUE(exists, NS_ERROR_FILE_NOT_FOUND);
-
-  bool isDir;
-  rv = file->IsDirectory(&isDir);
-  NS_ENSURE_SUCCESS(rv, rv);
-  NS_ENSURE_FALSE(isDir, NS_ERROR_FILE_IS_DIRECTORY);
-
-  mFile = file;
-  file->GetLeafName(mName);
-
-  return NS_OK;
-}
-
 ////////////////////////////////////////////////////////////////////////////
 // nsDOMMemoryFile implementation
 
 already_AddRefed<nsIDOMBlob>
 nsDOMMemoryFile::CreateSlice(uint64_t aStart, uint64_t aLength,
                              const nsAString& aContentType)
 {
   nsCOMPtr<nsIDOMBlob> t =
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -1784,17 +1784,17 @@ struct nsConstructorFuncMapData
   { eDOMClassInfo_##_class##_id, _func },
 
 #define NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(_class)   \
   { eDOMClassInfo_##_class##_id, NS_DOM##_class##Ctor },
 
 static const nsConstructorFuncMapData kConstructorFuncMap[] =
 {
   NS_DEFINE_CONSTRUCTOR_FUNC_DATA(Blob, nsDOMMultipartFile::NewBlob)
-  NS_DEFINE_CONSTRUCTOR_FUNC_DATA(File, nsDOMFileFile::NewFile)
+  NS_DEFINE_CONSTRUCTOR_FUNC_DATA(File, nsDOMMultipartFile::NewFile)
   NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(Event)
   NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(UIEvent)
   NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(MouseEvent)
   NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(WheelEvent)
 #ifdef MOZ_B2G_RIL
   NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(MozWifiStatusChangeEvent)
   NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(MozWifiConnectionInfoEvent)
 #endif
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -2540,16 +2540,23 @@ nsDOMWindowUtils::PreventFurtherDialogs(
 
   nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
   NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
 
   static_cast<nsGlobalWindow*>(window.get())->PreventFurtherDialogs(true);
   return NS_OK;
 }
 
+static nsIDOMBlob*
+GetXPConnectNative(JSContext* aCx, JSObject* aObj) {
+  nsCOMPtr<nsIDOMBlob> blob = do_QueryInterface(
+    nsContentUtils::XPConnect()->GetNativeOfWrapper(aCx, aObj));
+  return blob;
+}
+
 static nsresult
 GetFileOrBlob(const nsAString& aName, const jsval& aBlobParts,
               const jsval& aParameters, JSContext* aCx,
               uint8_t aOptionalArgCount, nsISupports** aResult)
 {
   if (!nsContentUtils::IsCallerChrome()) {
     return NS_ERROR_DOM_SECURITY_ERR;
   }
@@ -2561,22 +2568,22 @@ GetFileOrBlob(const nsAString& aName, co
   if (aName.IsVoid()) {
     rv = nsDOMMultipartFile::NewBlob(getter_AddRefs(file));
   }
   else {
     rv = nsDOMMultipartFile::NewFile(aName, getter_AddRefs(file));
   }
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsCOMPtr<nsIJSNativeInitializer> initializer = do_QueryInterface(file);
-  NS_ASSERTION(initializer, "what?");
+  nsDOMMultipartFile* domFile =
+    static_cast<nsDOMMultipartFile*>(static_cast<nsIDOMFile*>(file.get()));
 
   jsval args[2] = { aBlobParts, aParameters };
 
-  rv = initializer->Initialize(nullptr, aCx, nullptr, aOptionalArgCount, args);
+  rv = domFile->InitBlob(aCx, aOptionalArgCount, args, GetXPConnectNative);
   NS_ENSURE_SUCCESS(rv, rv);
 
   file.forget(aResult);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMWindowUtils::GetFile(const nsAString& aName, const jsval& aBlobParts,
new file mode 100644
--- /dev/null
+++ b/dom/webidl/File.webidl
@@ -0,0 +1,9 @@
+/* -*- Mode: IDL; 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/.
+ */
+
+dictionary FilePropertyBag : BlobPropertyBag {
+  DOMString name = "";
+};
--- a/dom/webidl/WebIDL.mk
+++ b/dom/webidl/WebIDL.mk
@@ -26,16 +26,17 @@ webidl_files = \
   DOMImplementation.webidl \
   DOMTokenList.webidl \
   DOMSettableTokenList.webidl \
   DOMStringMap.webidl \
   DynamicsCompressorNode.webidl \
   EventHandler.webidl \
   EventListener.webidl \
   EventTarget.webidl \
+  File.webidl \
   FileList.webidl \
   FileReaderSync.webidl \
   GainNode.webidl \
   HTMLCollection.webidl \
   HTMLOptionsCollection.webidl \
   HTMLPropertiesCollection.webidl \
   ImageData.webidl \
   NodeList.webidl \
--- a/dom/workers/File.cpp
+++ b/dom/workers/File.cpp
@@ -83,18 +83,17 @@ private:
   {
     return GetPrivate(aObj);
   }
 
   static JSBool
   Construct(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
     nsRefPtr<nsDOMMultipartFile> file = new nsDOMMultipartFile();
-    nsresult rv = file->InitInternal(aCx, aArgc, JS_ARGV(aCx, aVp),
-                                     Unwrap);
+    nsresult rv = file->InitBlob(aCx, aArgc, JS_ARGV(aCx, aVp), Unwrap);
     if (NS_FAILED(rv)) {
       ThrowDOMExceptionForNSResult(aCx, rv);
       return false;
     }
 
     JSObject* obj = file::CreateBlob(aCx, file);
     if (!obj) {
       return false;
--- a/js/xpconnect/loader/Makefile.in
+++ b/js/xpconnect/loader/Makefile.in
@@ -8,18 +8,21 @@ srcdir		= @srcdir@
 VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE		= jsloader
 LIBRARY_NAME	= jsloader_s
 FORCE_STATIC_LIB = 1
 LIBXUL_LIBRARY = 1
-LOCAL_INCLUDES += -I$(srcdir)/../src \
-                  -I$(srcdir)/../wrappers
+LOCAL_INCLUDES += \
+  -I$(srcdir)/../src \
+  -I$(srcdir)/../wrappers \
+  -I$(topsrcdir)/content/base/src \
+  $(NULL)
 
 CPPSRCS		= mozJSComponentLoader.cpp mozJSSubScriptLoader.cpp mozJSLoaderUtils.cpp
 
 EXTRA_JS_MODULES = XPCOMUtils.jsm ISO8601DateUtils.jsm
 
 include $(topsrcdir)/config/rules.mk
 
 DEFINES += \
--- a/js/xpconnect/loader/mozJSComponentLoader.cpp
+++ b/js/xpconnect/loader/mozJSComponentLoader.cpp
@@ -38,17 +38,17 @@
 #include "nsIObserverService.h"
 #include "nsIXPCScriptable.h"
 #include "nsString.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsIURI.h"
 #include "nsIFileURL.h"
 #include "nsIJARURI.h"
 #include "nsNetUtil.h"
-#include "nsDOMFile.h"
+#include "nsDOMBlobBuilder.h"
 #include "jsprf.h"
 #include "nsJSPrincipals.h"
 // For reporting errors with the console service
 #include "nsIScriptError.h"
 #include "nsIConsoleService.h"
 #include "nsIStorageStream.h"
 #include "nsIStringStream.h"
 #if defined(XP_WIN)
@@ -240,17 +240,17 @@ File(JSContext *cx, unsigned argc, jsval
     nsresult rv;
 
     if (!argc) {
         XPCThrower::Throw(NS_ERROR_UNEXPECTED, cx);
         return false;
     }
 
     nsCOMPtr<nsISupports> native;
-    rv = nsDOMFileFile::NewFile(getter_AddRefs(native));
+    rv = nsDOMMultipartFile::NewFile(getter_AddRefs(native));
     if (NS_FAILED(rv)) {
         XPCThrower::Throw(rv, cx);
         return false;
     }
 
     nsCOMPtr<nsIJSNativeInitializer> initializer = do_QueryInterface(native);
     NS_ASSERTION(initializer, "what?");
 
--- a/js/xpconnect/tests/unit/component-file.js
+++ b/js/xpconnect/tests/unit/component-file.js
@@ -30,41 +30,32 @@ FileComponent.prototype =
 
     // should be able to construct a file
     var f1 = File(file.path);
     // with either constructor syntax
     var f2 = new File(file.path);
     // and with nsIFiles
     var f3 = File(file);
     var f4 = new File(file);
-    // and extra args are ignored
-    var f5 = File(file.path, "foopy");
-    var f6 = new File(file, Date(123123154));
 
     // do some tests
     do_check_true(f1 instanceof Ci.nsIDOMFile, "Should be a DOM File");
     do_check_true(f2 instanceof Ci.nsIDOMFile, "Should be a DOM File");
     do_check_true(f3 instanceof Ci.nsIDOMFile, "Should be a DOM File");
     do_check_true(f4 instanceof Ci.nsIDOMFile, "Should be a DOM File");
-    do_check_true(f5 instanceof Ci.nsIDOMFile, "Should be a DOM File");
-    do_check_true(f6 instanceof Ci.nsIDOMFile, "Should be a DOM File");
 
     do_check_true(f1.name == "xpcshell.ini", "Should be the right file");
     do_check_true(f2.name == "xpcshell.ini", "Should be the right file");
     do_check_true(f3.name == "xpcshell.ini", "Should be the right file");
     do_check_true(f4.name == "xpcshell.ini", "Should be the right file");
-    do_check_true(f5.name == "xpcshell.ini", "Should be the right file");
-    do_check_true(f6.name == "xpcshell.ini", "Should be the right file");
 
     do_check_true(f1.type = "text/plain", "Should be the right type");
     do_check_true(f2.type = "text/plain", "Should be the right type");
     do_check_true(f3.type = "text/plain", "Should be the right type");
     do_check_true(f4.type = "text/plain", "Should be the right type");
-    do_check_true(f5.type = "text/plain", "Should be the right type");
-    do_check_true(f6.type = "text/plain", "Should be the right type");
 
     var threw = false;
     try {
       // Needs a ctor argument
       var f7 = File();
     } catch (e) {
       threw = true;
     }