diff --git a/content/base/public/nsDOMFile.h b/content/base/public/nsDOMFile.h index b6feedb290c..f15e3ffbdfa 100644 --- a/content/base/public/nsDOMFile.h +++ b/content/base/public/nsDOMFile.h @@ -201,8 +201,7 @@ public: NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsDOMFileCC, nsIDOMFile) }; -class nsDOMFileFile : public nsDOMFile, - public nsIJSNativeInitializer +class nsDOMFileFile : public nsDOMFile { public: // Create as a file @@ -290,15 +289,6 @@ public: 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); @@ -307,10 +297,6 @@ public: 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, diff --git a/content/base/src/nsDOMBlobBuilder.cpp b/content/base/src/nsDOMBlobBuilder.cpp index 24cde932a8a..7a9fbff8a71 100644 --- a/content/base/src/nsDOMBlobBuilder.cpp +++ b/content/base/src/nsDOMBlobBuilder.cpp @@ -6,6 +6,7 @@ #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" @@ -171,14 +172,17 @@ nsDOMMultipartFile::Initialize(nsISupports* aOwner, 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) { @@ -260,6 +264,96 @@ nsDOMMultipartFile::InitInternal(JSContext* aCx, 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 file; + nsCOMPtr 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); + + 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) { diff --git a/content/base/src/nsDOMBlobBuilder.h b/content/base/src/nsDOMBlobBuilder.h index 4d1bd6fdfb3..ee940d4e209 100644 --- a/content/base/src/nsDOMBlobBuilder.h +++ b/content/base/src/nsDOMBlobBuilder.h @@ -54,10 +54,13 @@ public: 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 CreateSlice(uint64_t aStart, uint64_t aLength, const nsAString& aContentType); @@ -72,6 +75,16 @@ public: 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 >* GetSubBlobs() const { return &mBlobs; } diff --git a/content/base/src/nsDOMFile.cpp b/content/base/src/nsDOMFile.cpp index 49eace0c23d..edc64a5ccbc 100644 --- a/content/base/src/nsDOMFile.cpp +++ b/content/base/src/nsDOMFile.cpp @@ -470,9 +470,6 @@ NS_IMPL_CYCLE_COLLECTING_RELEASE(nsDOMFileCC) //////////////////////////////////////////////////////////////////////////// // nsDOMFileFile implementation -NS_IMPL_ISUPPORTS_INHERITED1(nsDOMFileFile, nsDOMFile, - nsIJSNativeInitializer) - already_AddRefed nsDOMFileFile::CreateSlice(uint64_t aStart, uint64_t aLength, const nsAString& aContentType) @@ -481,14 +478,6 @@ nsDOMFileFile::CreateSlice(uint64_t aStart, uint64_t aLength, return t.forget(); } -/* static */ nsresult -nsDOMFileFile::NewFile(nsISupports* *aNewObject) -{ - nsCOMPtr file = do_QueryObject(new nsDOMFileFile()); - file.forget(aNewObject); - return NS_OK; -} - NS_IMETHODIMP nsDOMFileFile::GetMozFullPathInternal(nsAString &aFilename) { @@ -593,71 +582,6 @@ nsDOMFileFile::GetInternalStream(nsIInputStream **aStream) -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 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 diff --git a/dom/base/nsDOMClassInfo.cpp b/dom/base/nsDOMClassInfo.cpp index 562a0e794c8..11e9e907821 100644 --- a/dom/base/nsDOMClassInfo.cpp +++ b/dom/base/nsDOMClassInfo.cpp @@ -1757,7 +1757,7 @@ struct nsConstructorFuncMapData 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) diff --git a/dom/webidl/File.webidl b/dom/webidl/File.webidl new file mode 100644 index 00000000000..f4d085e29fe --- /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 = ""; +}; diff --git a/dom/webidl/WebIDL.mk b/dom/webidl/WebIDL.mk index a4fd17761d9..683666aef5b 100644 --- a/dom/webidl/WebIDL.mk +++ b/dom/webidl/WebIDL.mk @@ -33,6 +33,7 @@ webidl_files = \ EventHandler.webidl \ EventListener.webidl \ EventTarget.webidl \ + File.webidl \ FileHandle.webidl \ FileList.webidl \ FileReaderSync.webidl \ diff --git a/dom/workers/File.cpp b/dom/workers/File.cpp index 674fc9d9236..047c0ca61cd 100644 --- a/dom/workers/File.cpp +++ b/dom/workers/File.cpp @@ -88,8 +88,7 @@ private: Construct(JSContext* aCx, unsigned aArgc, jsval* aVp) { nsRefPtr 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; diff --git a/js/xpconnect/loader/Makefile.in b/js/xpconnect/loader/Makefile.in index 0d576b6cc31..1a1d7e5a5d9 100644 --- a/js/xpconnect/loader/Makefile.in +++ b/js/xpconnect/loader/Makefile.in @@ -13,8 +13,11 @@ 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 diff --git a/js/xpconnect/loader/mozJSComponentLoader.cpp b/js/xpconnect/loader/mozJSComponentLoader.cpp index 12bfc1e7e8d..e68cab25a3d 100644 --- a/js/xpconnect/loader/mozJSComponentLoader.cpp +++ b/js/xpconnect/loader/mozJSComponentLoader.cpp @@ -43,7 +43,7 @@ #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 @@ -245,7 +245,7 @@ File(JSContext *cx, unsigned argc, jsval *vp) } nsCOMPtr native; - rv = nsDOMFileFile::NewFile(getter_AddRefs(native)); + rv = nsDOMMultipartFile::NewFile(getter_AddRefs(native)); if (NS_FAILED(rv)) { XPCThrower::Throw(rv, cx); return false;