--- a/b2g/components/FilePicker.js
+++ b/b2g/components/FilePicker.js
@@ -202,19 +202,19 @@ FilePicker.prototype = {
let mimeSvc = Cc["@mozilla.org/mime;1"].getService(Ci.nsIMIMEService);
let mimeInfo = mimeSvc.getFromTypeAndExtension(data.result.blob.type, '');
if (mimeInfo) {
name += '.' + mimeInfo.primaryExtension;
}
}
}
- let file = new this.mParent.File(data.result.blob,
- { name: name,
- type: data.result.blob.type });
+ let file = new this.mParent.File([data.result.blob],
+ name,
+ { type: data.result.blob.type });
if (file) {
this.fireSuccess(file);
} else {
this.fireError();
}
}
};
--- a/browser/base/content/test/general/browser_blob-channelname.js
+++ b/browser/base/content/test/general/browser_blob-channelname.js
@@ -1,11 +1,11 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
Cu.import("resource://gre/modules/NetUtil.jsm");
function test() {
- var file = new File(new Blob(['test'], {type: 'text/plain'}), {name: 'test-name'});
+ var file = new File([new Blob(['test'], {type: 'text/plain'})], "test-name");
var url = URL.createObjectURL(file);
var channel = NetUtil.newChannel(url);
is(channel.contentDispositionFilename, 'test-name', "filename matches");
}
--- a/content/base/public/nsContentUtils.h
+++ b/content/base/public/nsContentUtils.h
@@ -1664,16 +1664,17 @@ public:
/**
* Creates an arraybuffer from a binary string.
*/
static nsresult CreateArrayBuffer(JSContext *aCx, const nsACString& aData,
JSObject** aResult);
static nsresult CreateBlobBuffer(JSContext* aCx,
+ nsISupports* aParent,
const nsACString& aData,
JS::MutableHandle<JS::Value> aBlob);
static void StripNullChars(const nsAString& aInStr, nsAString& aOutStr);
/**
* Strip all \n, \r and nulls from the given string
* @param aString the string to remove newlines from [in/out]
--- a/content/base/public/nsDOMFile.h
+++ b/content/base/public/nsDOMFile.h
@@ -1,43 +1,38 @@
/* -*- 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/. */
-#ifndef nsDOMFile_h__
-#define nsDOMFile_h__
+#ifndef mozilla_dom_DOMFile_h
+#define mozilla_dom_DOMFile_h
#include "mozilla/Attributes.h"
-#include "nsICharsetDetectionObserver.h"
-#include "nsIFile.h"
-#include "nsIDOMFile.h"
-#include "nsIDOMFileList.h"
-#include "nsIInputStream.h"
-#include "nsIJSNativeInitializer.h"
-#include "nsIMutable.h"
-#include "nsCOMArray.h"
-#include "nsCOMPtr.h"
-#include "nsString.h"
-#include "nsIXMLHttpRequest.h"
-#include "nsAutoPtr.h"
-#include "nsFileStreams.h"
-#include "nsTemporaryFileInputStream.h"
#include "mozilla/GuardObjects.h"
#include "mozilla/LinkedList.h"
-#include <stdint.h>
#include "mozilla/StaticMutex.h"
#include "mozilla/StaticPtr.h"
-#include "mozilla/dom/DOMError.h"
+#include "mozilla/dom/Date.h"
#include "mozilla/dom/indexedDB/FileInfo.h"
#include "mozilla/dom/indexedDB/FileManager.h"
#include "mozilla/dom/indexedDB/IndexedDatabaseManager.h"
+#include "mozilla/dom/UnionTypes.h"
+#include "nsAutoPtr.h"
+#include "nsCycleCollectionParticipant.h"
+#include "nsCOMPtr.h"
+#include "nsIDOMFile.h"
+#include "nsIDOMFileList.h"
+#include "nsIFile.h"
+#include "nsIMutable.h"
+#include "nsIXMLHttpRequest.h"
+#include "nsString.h"
+#include "nsTemporaryFileInputStream.h"
#include "nsWrapperCache.h"
-#include "nsCycleCollectionParticipant.h"
#include "nsWeakReference.h"
class nsDOMMultipartFile;
class nsIFile;
class nsIInputStream;
class nsIClassInfo;
#define PIDOMFILEIMPL_IID \
@@ -54,86 +49,93 @@ NS_DEFINE_STATIC_IID_ACCESSOR(PIDOMFileI
namespace mozilla {
namespace dom {
namespace indexedDB {
class FileInfo;
};
+struct BlobPropertyBag;
+struct FilePropertyBag;
class DOMFileImpl;
+/* FOLLOWUP TODO:
+1. remove nsDOMBlobBuilder.h
+2. rename nsDOMFile.h/cpp to DOMFile.h/cpp
+3. rename nsDOMFileList to DOMFileList
+*/
class DOMFile MOZ_FINAL : public nsIDOMFile
, public nsIXHRSendable
, public nsIMutable
- , public nsIJSNativeInitializer
, public nsSupportsWeakReference
+ , public nsWrapperCache
{
public:
NS_DECL_NSIDOMBLOB
NS_DECL_NSIDOMFILE
NS_DECL_NSIXHRSENDABLE
NS_DECL_NSIMUTABLE
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
- NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(DOMFile, nsIDOMFile)
+ NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(DOMFile, nsIDOMFile)
static already_AddRefed<DOMFile>
- Create(const nsAString& aName, const nsAString& aContentType,
- uint64_t aLength, uint64_t aLastModifiedDate);
+ Create(nsISupports* aParent, const nsAString& aName,
+ const nsAString& aContentType, uint64_t aLength,
+ uint64_t aLastModifiedDate);
static already_AddRefed<DOMFile>
- Create(const nsAString& aName, const nsAString& aContentType,
+ Create(nsISupports* aParent, const nsAString& aName,
+ const nsAString& aContentType, uint64_t aLength);
+
+ static already_AddRefed<DOMFile>
+ Create(nsISupports* aParent, const nsAString& aContentType,
uint64_t aLength);
static already_AddRefed<DOMFile>
- Create(const nsAString& aContentType, uint64_t aLength);
-
- static already_AddRefed<DOMFile>
- Create(const nsAString& aContentType, uint64_t aStart,
+ Create(nsISupports* aParent, const nsAString& aContentType, uint64_t aStart,
uint64_t aLength);
static already_AddRefed<DOMFile>
- CreateMemoryFile(void* aMemoryBuffer, uint64_t aLength,
+ CreateMemoryFile(nsISupports* aParent, void* aMemoryBuffer, uint64_t aLength,
const nsAString& aName, const nsAString& aContentType,
uint64_t aLastModifiedDate);
static already_AddRefed<DOMFile>
- CreateMemoryFile(void* aMemoryBuffer, uint64_t aLength,
+ CreateMemoryFile(nsISupports* aParent, void* aMemoryBuffer, uint64_t aLength,
const nsAString& aContentType);
static already_AddRefed<DOMFile>
- CreateTemporaryFileBlob(PRFileDesc* aFD, uint64_t aStartPos,
- uint64_t aLength,
+ CreateTemporaryFileBlob(nsISupports* aParent, PRFileDesc* aFD,
+ uint64_t aStartPos, uint64_t aLength,
const nsAString& aContentType);
static already_AddRefed<DOMFile>
- CreateFromFile(nsIFile* aFile);
+ CreateFromFile(nsISupports* aParent, nsIFile* aFile);
static already_AddRefed<DOMFile>
- CreateFromFile(const nsAString& aContentType, uint64_t aLength,
+ CreateFromFile(nsISupports* aParent, const nsAString& aContentType,
+ uint64_t aLength, nsIFile* aFile,
+ indexedDB::FileInfo* aFileInfo);
+
+ static already_AddRefed<DOMFile>
+ CreateFromFile(nsISupports* aParent, const nsAString& aName,
+ const nsAString& aContentType, uint64_t aLength,
nsIFile* aFile, indexedDB::FileInfo* aFileInfo);
static already_AddRefed<DOMFile>
- CreateFromFile(const nsAString& aName, const nsAString& aContentType,
- uint64_t aLength, nsIFile* aFile,
- indexedDB::FileInfo* aFileInfo);
-
- static already_AddRefed<DOMFile>
- CreateFromFile(nsIFile* aFile, indexedDB::FileInfo* aFileInfo);
+ CreateFromFile(nsISupports* aParent, nsIFile* aFile,
+ indexedDB::FileInfo* aFileInfo);
static already_AddRefed<DOMFile>
- CreateFromFile(nsIFile* aFile, const nsAString& aName,
+ CreateFromFile(nsISupports* aParent, nsIFile* aFile, const nsAString& aName,
const nsAString& aContentType);
- explicit DOMFile(DOMFileImpl* aImpl)
- : mImpl(aImpl)
- {
- MOZ_ASSERT(mImpl);
- }
+ DOMFile(nsISupports* aParent, DOMFileImpl* aImpl);
DOMFileImpl* Impl() const
{
return mImpl;
}
const nsTArray<nsRefPtr<DOMFileImpl>>* GetSubBlobImpls() const;
@@ -141,67 +143,127 @@ public:
bool IsDateUnknown() const;
bool IsFile() const;
void SetLazyData(const nsAString& aName, const nsAString& aContentType,
uint64_t aLength, uint64_t aLastModifiedDate);
- already_AddRefed<nsIDOMBlob>
- CreateSlice(uint64_t aStart, uint64_t aLength,
- const nsAString& aContentType);
+ already_AddRefed<DOMFile>
+ CreateSlice(uint64_t aStart, uint64_t aLength, const nsAString& aContentType,
+ ErrorResult& aRv);
+
+ // WebIDL methods
+ nsISupports* GetParentObject() const
+ {
+ return mParent;
+ }
+
+ // Blob constructor
+ static already_AddRefed<DOMFile>
+ Constructor(const GlobalObject& aGlobal, ErrorResult& aRv);
+
+ // Blob constructor
+ static already_AddRefed<DOMFile>
+ Constructor(const GlobalObject& aGlobal,
+ const Sequence<OwningArrayBufferOrArrayBufferViewOrBlobOrString>& aData,
+ const BlobPropertyBag& aBag,
+ ErrorResult& aRv);
+
+ // File constructor
+ static already_AddRefed<DOMFile>
+ Constructor(const GlobalObject& aGlobal,
+ const Sequence<OwningArrayBufferOrArrayBufferViewOrBlobOrString>& aData,
+ const nsAString& aName,
+ const FilePropertyBag& aBag,
+ ErrorResult& aRv);
- // nsIJSNativeInitializer
- NS_IMETHOD Initialize(nsISupports* aOwner, JSContext* aCx, JSObject* aObj,
- const JS::CallArgs& aArgs) MOZ_OVERRIDE;
+ // File constructor - ChromeOnly
+ static already_AddRefed<DOMFile>
+ Constructor(const GlobalObject& aGlobal,
+ DOMFile& aData,
+ const FilePropertyBag& aBag,
+ ErrorResult& aRv);
+
+ // File constructor - ChromeOnly
+ static already_AddRefed<DOMFile>
+ Constructor(const GlobalObject& aGlobal,
+ const nsAString& aData,
+ const FilePropertyBag& aBag,
+ ErrorResult& aRv);
+
+ // File constructor - ChromeOnly
+ static already_AddRefed<DOMFile>
+ Constructor(const GlobalObject& aGlobal,
+ nsIFile* aData,
+ const FilePropertyBag& aBag,
+ ErrorResult& aRv);
+
+ virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+
+ uint64_t GetSize(ErrorResult& aRv);
+
+ // XPCOM GetType is OK
+
+ // XPCOM GetName is OK
+
+ int64_t GetLastModified(ErrorResult& aRv);
+
+ Date GetLastModifiedDate(ErrorResult& aRv);
+
+ void GetMozFullPath(nsAString& aFilename, ErrorResult& aRv);
+
+ already_AddRefed<DOMFile> Slice(const Optional<int64_t>& aStart,
+ const Optional<int64_t>& aEnd,
+ const nsAString& aContentType,
+ ErrorResult& aRv);
private:
~DOMFile() {};
// The member is the real backend implementation of this DOMFile/DOMBlob.
// It's thread-safe and not CC-able and it's the only element that is moved
// between threads.
// Note: we should not store any other state in this class!
const nsRefPtr<DOMFileImpl> mImpl;
+
+ nsCOMPtr<nsISupports> mParent;
};
// This is the abstract class for any DOMFile backend. It must be nsISupports
// because this class must be ref-counted and it has to work with IPC.
class DOMFileImpl : public PIDOMFileImpl
{
public:
NS_DECL_THREADSAFE_ISUPPORTS
DOMFileImpl() {}
- virtual nsresult GetName(nsAString& aName) = 0;
+ virtual void GetName(nsAString& aName) = 0;
virtual nsresult GetPath(nsAString& aName) = 0;
- virtual nsresult
- GetLastModifiedDate(JSContext* aCx,
- JS::MutableHandle<JS::Value> aDate) = 0;
+ virtual int64_t GetLastModified(ErrorResult& aRv) = 0;
- virtual nsresult GetMozFullPath(nsAString& aName) = 0;
+ virtual void GetMozFullPath(nsAString& aName, ErrorResult& aRv) = 0;
- virtual nsresult GetMozFullPathInternal(nsAString &aFileName) = 0;
+ virtual void GetMozFullPathInternal(nsAString& aFileName, ErrorResult& aRv) = 0;
- virtual nsresult GetSize(uint64_t* aSize) = 0;
+ virtual uint64_t GetSize(ErrorResult& aRv) = 0;
- virtual nsresult GetType(nsAString& aType) = 0;
+ virtual void GetType(nsAString& aType) = 0;
- virtual nsresult GetMozLastModifiedDate(uint64_t* aDate) = 0;
-
- nsresult Slice(int64_t aStart, int64_t aEnd, const nsAString& aContentType,
- uint8_t aArgc, DOMFileImpl** aBlobImpl);
+ already_AddRefed<DOMFileImpl>
+ Slice(const Optional<int64_t>& aStart, const Optional<int64_t>& aEnd,
+ const nsAString& aContentType, ErrorResult& aRv);
virtual already_AddRefed<DOMFileImpl>
CreateSlice(uint64_t aStart, uint64_t aLength,
- const nsAString& aContentType) = 0;
+ const nsAString& aContentType, ErrorResult& aRv) = 0;
virtual const nsTArray<nsRefPtr<DOMFileImpl>>*
GetSubBlobImpls() const = 0;
virtual nsresult GetInternalStream(nsIInputStream** aStream) = 0;
virtual int64_t GetFileId() = 0;
@@ -227,19 +289,16 @@ public:
virtual bool IsMemoryFile() const = 0;
virtual bool IsSizeUnknown() const = 0;
virtual bool IsDateUnknown() const = 0;
virtual bool IsFile() const = 0;
- virtual nsresult Initialize(nsISupports* aOwner, JSContext* aCx,
- JSObject* aObj, const JS::CallArgs& aArgs) = 0;
-
// These 2 methods are used when the implementation has to CC something.
virtual void Unlink() = 0;
virtual void Traverse(nsCycleCollectionTraversalCallback &aCb) = 0;
virtual bool IsCCed() const
{
return false;
}
@@ -301,44 +360,51 @@ public:
, mLastModificationDate(UINT64_MAX)
{
NS_ASSERTION(aLength != UINT64_MAX,
"Must know length when creating slice");
// Ensure non-null mContentType by default
mContentType.SetIsVoid(false);
}
- virtual nsresult GetName(nsAString& aName) MOZ_OVERRIDE;
+ virtual void GetName(nsAString& aName) MOZ_OVERRIDE;
virtual nsresult GetPath(nsAString& aName) MOZ_OVERRIDE;
- virtual nsresult GetLastModifiedDate(JSContext* aCx,
- JS::MutableHandle<JS::Value> aDate) MOZ_OVERRIDE;
+ virtual int64_t GetLastModified(ErrorResult& aRv) MOZ_OVERRIDE;
- virtual nsresult GetMozFullPath(nsAString& aName) MOZ_OVERRIDE;
+ virtual void GetMozFullPath(nsAString& aName, ErrorResult& aRv) MOZ_OVERRIDE;
+
+ virtual void GetMozFullPathInternal(nsAString& aFileName,
+ ErrorResult& aRv) MOZ_OVERRIDE;
- virtual nsresult GetMozFullPathInternal(nsAString& aFileName) MOZ_OVERRIDE;
-
- virtual nsresult GetSize(uint64_t* aSize) MOZ_OVERRIDE;
+ virtual uint64_t GetSize(ErrorResult& aRv) MOZ_OVERRIDE
+ {
+ return mLength;
+ }
- virtual nsresult GetType(nsAString& aType) MOZ_OVERRIDE;
-
- virtual nsresult GetMozLastModifiedDate(uint64_t* aDate) MOZ_OVERRIDE;
+ virtual void GetType(nsAString& aType) MOZ_OVERRIDE;
virtual already_AddRefed<DOMFileImpl>
CreateSlice(uint64_t aStart, uint64_t aLength,
- const nsAString& aContentType) MOZ_OVERRIDE;
+ const nsAString& aContentType, ErrorResult& aRv) MOZ_OVERRIDE
+ {
+ return nullptr;
+ }
virtual const nsTArray<nsRefPtr<DOMFileImpl>>*
GetSubBlobImpls() const MOZ_OVERRIDE
{
return nullptr;
}
- virtual nsresult GetInternalStream(nsIInputStream** aStream) MOZ_OVERRIDE;
+ virtual nsresult GetInternalStream(nsIInputStream** aStream) MOZ_OVERRIDE
+ {
+ return NS_ERROR_NOT_IMPLEMENTED;
+ }
virtual int64_t GetFileId() MOZ_OVERRIDE;
virtual void AddFileInfo(indexedDB::FileInfo* aFileInfo) MOZ_OVERRIDE;
virtual indexedDB::FileInfo*
GetFileInfo(indexedDB::FileManager* aFileManager) MOZ_OVERRIDE;
@@ -395,22 +461,16 @@ public:
return false;
}
virtual bool IsSizeUnknown() const
{
return mLength == UINT64_MAX;
}
- virtual nsresult Initialize(nsISupports* aOwner, JSContext* aCx,
- JSObject* aObj, const JS::CallArgs& aArgs)
- {
- return NS_OK;
- }
-
virtual void Unlink() {}
virtual void Traverse(nsCycleCollectionTraversalCallback &aCb) {}
protected:
virtual ~DOMFileImplBase() {}
indexedDB::FileInfo* GetFileInfo() const
{
@@ -463,17 +523,17 @@ public:
{
NS_ASSERTION(mDataOwner && mDataOwner->mData, "must have data");
}
virtual nsresult GetInternalStream(nsIInputStream** aStream) MOZ_OVERRIDE;
virtual already_AddRefed<DOMFileImpl>
CreateSlice(uint64_t aStart, uint64_t aLength,
- const nsAString& aContentType) MOZ_OVERRIDE;
+ const nsAString& aContentType, ErrorResult& aRv) MOZ_OVERRIDE;
virtual bool IsMemoryFile() const MOZ_OVERRIDE
{
return true;
}
class DataOwner MOZ_FINAL : public mozilla::LinkedListElement<DataOwner> {
public:
@@ -550,17 +610,17 @@ public:
{
mFileDescOwner = new nsTemporaryFileInputStream::FileDescOwner(aFD);
}
virtual nsresult GetInternalStream(nsIInputStream** aStream) MOZ_OVERRIDE;
virtual already_AddRefed<DOMFileImpl>
CreateSlice(uint64_t aStart, uint64_t aLength,
- const nsAString& aContentType) MOZ_OVERRIDE;
+ const nsAString& aContentType, ErrorResult& aRv) MOZ_OVERRIDE;
private:
DOMFileImplTemporaryFileBlob(const DOMFileImplTemporaryFileBlob* aOther,
uint64_t aStart, uint64_t aLength,
const nsAString& aContentType)
: DOMFileImplBase(aContentType, aLength)
, mLength(aLength)
, mStartPos(aStart)
@@ -677,22 +737,21 @@ public:
, mStoredFile(false)
{
// Lazily get the content type and size
mContentType.SetIsVoid(true);
mName.SetIsVoid(true);
}
// Overrides
- virtual nsresult GetSize(uint64_t* aSize) MOZ_OVERRIDE;
- virtual nsresult GetType(nsAString& aType) MOZ_OVERRIDE;
- virtual nsresult GetLastModifiedDate(JSContext* aCx,
- JS::MutableHandle<JS::Value> aLastModifiedDate) MOZ_OVERRIDE;
- virtual nsresult GetMozLastModifiedDate(uint64_t* aLastModifiedDate) MOZ_OVERRIDE;
- virtual nsresult GetMozFullPathInternal(nsAString& aFullPath) MOZ_OVERRIDE;
+ virtual uint64_t GetSize(ErrorResult& aRv) MOZ_OVERRIDE;
+ virtual void GetType(nsAString& aType) MOZ_OVERRIDE;
+ virtual int64_t GetLastModified(ErrorResult& aRv) MOZ_OVERRIDE;
+ virtual void GetMozFullPathInternal(nsAString& aFullPath,
+ ErrorResult& aRv) MOZ_OVERRIDE;
virtual nsresult GetInternalStream(nsIInputStream**) MOZ_OVERRIDE;
void SetPath(const nsAString& aFullPath);
protected:
virtual ~DOMFileImplFile() {}
private:
@@ -721,36 +780,33 @@ private:
}
mFileInfos.AppendElement(fileInfo);
}
}
virtual already_AddRefed<DOMFileImpl>
CreateSlice(uint64_t aStart, uint64_t aLength,
- const nsAString& aContentType) MOZ_OVERRIDE;
+ const nsAString& aContentType, ErrorResult& aRv) MOZ_OVERRIDE;
virtual bool IsStoredFile() const MOZ_OVERRIDE
{
return mStoredFile;
}
virtual bool IsWholeFile() const MOZ_OVERRIDE
{
return mWholeFile;
}
nsCOMPtr<nsIFile> mFile;
bool mWholeFile;
bool mStoredFile;
};
-} // dom namespace
-} // file namespace
-
class nsDOMFileList MOZ_FINAL : public nsIDOMFileList,
public nsWrapperCache
{
~nsDOMFileList() {}
public:
explicit nsDOMFileList(nsISupports *aParent) : mParent(aParent)
{
@@ -768,19 +824,27 @@ public:
return mParent;
}
void Disconnect()
{
mParent = nullptr;
}
- bool Append(nsIDOMFile *aFile) { return mFiles.AppendObject(aFile); }
+ bool Append(DOMFile *aFile) { return mFiles.AppendElement(aFile); }
- bool Remove(uint32_t aIndex) { return mFiles.RemoveObjectAt(aIndex); }
+ bool Remove(uint32_t aIndex) {
+ if (aIndex < mFiles.Length()) {
+ mFiles.RemoveElementAt(aIndex);
+ return true;
+ }
+
+ return false;
+ }
+
void Clear() { return mFiles.Clear(); }
static nsDOMFileList* FromSupports(nsISupports* aSupports)
{
#ifdef DEBUG
{
nsCOMPtr<nsIDOMFileList> list_qi = do_QueryInterface(aSupports);
@@ -790,28 +854,31 @@ public:
NS_ASSERTION(list_qi == static_cast<nsIDOMFileList*>(aSupports),
"Uh, fix QI!");
}
#endif
return static_cast<nsDOMFileList*>(aSupports);
}
- nsIDOMFile* Item(uint32_t aIndex)
+ DOMFile* Item(uint32_t aIndex)
{
- return mFiles.SafeObjectAt(aIndex);
+ return mFiles.SafeElementAt(aIndex);
}
- nsIDOMFile* IndexedGetter(uint32_t aIndex, bool& aFound)
+ DOMFile* IndexedGetter(uint32_t aIndex, bool& aFound)
{
- aFound = aIndex < static_cast<uint32_t>(mFiles.Count());
- return aFound ? mFiles.ObjectAt(aIndex) : nullptr;
+ aFound = aIndex < mFiles.Length();
+ return aFound ? mFiles.ElementAt(aIndex) : nullptr;
}
uint32_t Length()
{
- return mFiles.Count();
+ return mFiles.Length();
}
private:
- nsCOMArray<nsIDOMFile> mFiles;
+ nsTArray<nsRefPtr<DOMFile>> mFiles;
nsISupports *mParent;
};
-#endif
+} // dom namespace
+} // file namespace
+
+#endif // mozilla_dom_DOMFile_h
--- a/content/base/src/WebSocket.cpp
+++ b/content/base/src/WebSocket.cpp
@@ -893,17 +893,17 @@ WebSocket::CreateAndDispatchMessageEvent
return NS_ERROR_FAILURE;
}
JSContext* cx = jsapi.cx();
// Create appropriate JS object for message
JS::Rooted<JS::Value> jsData(cx);
if (isBinary) {
if (mBinaryType == dom::BinaryType::Blob) {
- rv = nsContentUtils::CreateBlobBuffer(cx, aData, &jsData);
+ rv = nsContentUtils::CreateBlobBuffer(cx, GetOwner(), aData, &jsData);
NS_ENSURE_SUCCESS(rv, rv);
} else if (mBinaryType == dom::BinaryType::Arraybuffer) {
JS::Rooted<JSObject*> arrayBuf(cx);
rv = nsContentUtils::CreateArrayBuffer(cx, aData, arrayBuf.address());
NS_ENSURE_SUCCESS(rv, rv);
jsData = OBJECT_TO_JSVAL(arrayBuf);
} else {
NS_RUNTIMEABORT("Unknown binary type!");
@@ -1189,30 +1189,30 @@ WebSocket::Send(const nsAString& aData,
{
NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
NS_ConvertUTF16toUTF8 msgString(aData);
Send(nullptr, msgString, msgString.Length(), false, aRv);
}
void
-WebSocket::Send(nsIDOMBlob* aData,
+WebSocket::Send(DOMFile& aData,
ErrorResult& aRv)
{
NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
nsCOMPtr<nsIInputStream> msgStream;
- nsresult rv = aData->GetInternalStream(getter_AddRefs(msgStream));
+ nsresult rv = aData.GetInternalStream(getter_AddRefs(msgStream));
if (NS_FAILED(rv)) {
aRv.Throw(rv);
return;
}
uint64_t msgLength;
- rv = aData->GetSize(&msgLength);
+ rv = aData.GetSize(&msgLength);
if (NS_FAILED(rv)) {
aRv.Throw(rv);
return;
}
if (msgLength > UINT32_MAX) {
aRv.Throw(NS_ERROR_FILE_TOO_BIG);
return;
--- a/content/base/src/WebSocket.h
+++ b/content/base/src/WebSocket.h
@@ -27,16 +27,18 @@
#include "nsWrapperCache.h"
#define DEFAULT_WS_SCHEME_PORT 80
#define DEFAULT_WSS_SCHEME_PORT 443
namespace mozilla {
namespace dom {
+class DOMFile;
+
class WebSocket MOZ_FINAL : public DOMEventTargetHelper,
public nsIInterfaceRequestor,
public nsIWebSocketListener,
public nsIObserver,
public nsSupportsWeakReference,
public nsIRequest
{
friend class CallDispatchConnectionCloseEvents;
@@ -126,17 +128,17 @@ public: // WebIDL interface:
// webIDL: attribute DOMString binaryType;
dom::BinaryType BinaryType() const { return mBinaryType; }
void SetBinaryType(dom::BinaryType aData) { mBinaryType = aData; }
// webIDL: void send(DOMString|Blob|ArrayBufferView data);
void Send(const nsAString& aData,
ErrorResult& aRv);
- void Send(nsIDOMBlob* aData,
+ void Send(DOMFile& aData,
ErrorResult& aRv);
void Send(const ArrayBuffer& aData,
ErrorResult& aRv);
void Send(const ArrayBufferView& aData,
ErrorResult& aRv);
private: // constructor && distructor
explicit WebSocket(nsPIDOMWindow* aOwnerWindow);
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -85,16 +85,17 @@
#include "nsGkAtoms.h"
#include "nsHostObjectProtocolHandler.h"
#include "nsHtml5Module.h"
#include "nsHtml5StringParser.h"
#include "nsIAsyncVerifyRedirectCallback.h"
#include "nsICategoryManager.h"
#include "nsIChannelEventSink.h"
#include "nsIChannelPolicy.h"
+#include "nsICharsetDetectionObserver.h"
#include "nsIChromeRegistry.h"
#include "nsIConsoleService.h"
#include "nsIContent.h"
#include "nsIContentSecurityPolicy.h"
#include "nsIContentSink.h"
#include "nsIContentViewer.h"
#include "nsIDocShell.h"
#include "nsIDocument.h"
@@ -5987,30 +5988,36 @@ nsContentUtils::CreateArrayBuffer(JSCont
return NS_OK;
}
// Initial implementation: only stores to RAM, not file
// TODO: bug 704447: large file support
nsresult
nsContentUtils::CreateBlobBuffer(JSContext* aCx,
+ nsISupports* aParent,
const nsACString& aData,
JS::MutableHandle<JS::Value> aBlob)
{
uint32_t blobLen = aData.Length();
void* blobData = moz_malloc(blobLen);
- nsCOMPtr<nsIDOMBlob> blob;
+ nsRefPtr<DOMFile> blob;
if (blobData) {
memcpy(blobData, aData.BeginReading(), blobLen);
- blob = mozilla::dom::DOMFile::CreateMemoryFile(blobData, blobLen,
+ blob = mozilla::dom::DOMFile::CreateMemoryFile(aParent, blobData, blobLen,
EmptyString());
} else {
return NS_ERROR_OUT_OF_MEMORY;
}
- return nsContentUtils::WrapNative(aCx, blob, aBlob);
+
+ if (!WrapNewBindingObject(aCx, blob, aBlob)) {
+ return NS_ERROR_FAILURE;
+ }
+
+ return NS_OK;
}
void
nsContentUtils::StripNullChars(const nsAString& aInStr, nsAString& aOutStr)
{
// In common cases where we don't have nulls in the
// string we can simple simply bypass the checking code.
int32_t firstNullPos = aInStr.FindChar('\0');
--- a/content/base/src/nsDOMBlobBuilder.cpp
+++ b/content/base/src/nsDOMBlobBuilder.cpp
@@ -1,16 +1,15 @@
/* -*- 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"
@@ -19,23 +18,16 @@
#include <algorithm>
using namespace mozilla;
using namespace mozilla::dom;
NS_IMPL_ISUPPORTS_INHERITED0(DOMMultipartFileImpl, DOMFileImpl)
nsresult
-DOMMultipartFileImpl::GetSize(uint64_t* aLength)
-{
- *aLength = mLength;
- return NS_OK;
-}
-
-nsresult
DOMMultipartFileImpl::GetInternalStream(nsIInputStream** aStream)
{
nsresult rv;
*aStream = nullptr;
nsCOMPtr<nsIMultiplexInputStream> stream =
do_CreateInstance("@mozilla.org/io/multiplex-input-stream;1");
NS_ENSURE_TRUE(stream, NS_ERROR_FAILURE);
@@ -52,225 +44,145 @@ DOMMultipartFileImpl::GetInternalStream(
NS_ENSURE_SUCCESS(rv, rv);
}
return CallQueryInterface(stream, aStream);
}
already_AddRefed<DOMFileImpl>
DOMMultipartFileImpl::CreateSlice(uint64_t aStart, uint64_t aLength,
- const nsAString& aContentType)
+ const nsAString& aContentType,
+ ErrorResult& aRv)
{
// If we clamped to nothing we create an empty blob
nsTArray<nsRefPtr<DOMFileImpl>> blobImpls;
uint64_t length = aLength;
uint64_t skipStart = aStart;
// Prune the list of blobs if we can
uint32_t i;
for (i = 0; length && skipStart && i < mBlobImpls.Length(); i++) {
DOMFileImpl* blobImpl = mBlobImpls[i].get();
- uint64_t l;
- nsresult rv = blobImpl->GetSize(&l);
- NS_ENSURE_SUCCESS(rv, nullptr);
+ uint64_t l = blobImpl->GetSize(aRv);
+ if (NS_WARN_IF(aRv.Failed())) {
+ return nullptr;
+ }
if (skipStart < l) {
uint64_t upperBound = std::min<uint64_t>(l - skipStart, length);
- nsRefPtr<DOMFileImpl> firstImpl;
- rv = blobImpl->Slice(skipStart, skipStart + upperBound, aContentType, 3,
- getter_AddRefs(firstImpl));
- NS_ENSURE_SUCCESS(rv, nullptr);
+ nsRefPtr<DOMFileImpl> firstBlobImpl =
+ blobImpl->CreateSlice(skipStart, upperBound,
+ aContentType, aRv);
+ if (NS_WARN_IF(aRv.Failed())) {
+ return nullptr;
+ }
// Avoid wrapping a single blob inside an DOMMultipartFileImpl
if (length == upperBound) {
- return firstImpl.forget();
+ return firstBlobImpl.forget();
}
- blobImpls.AppendElement(firstImpl);
+ blobImpls.AppendElement(firstBlobImpl);
length -= upperBound;
i++;
break;
}
skipStart -= l;
}
// Now append enough blobs until we're done
for (; length && i < mBlobImpls.Length(); i++) {
DOMFileImpl* blobImpl = mBlobImpls[i].get();
- uint64_t l;
- nsresult rv = blobImpl->GetSize(&l);
- NS_ENSURE_SUCCESS(rv, nullptr);
+ uint64_t l = blobImpl->GetSize(aRv);
+ if (NS_WARN_IF(aRv.Failed())) {
+ return nullptr;
+ }
if (length < l) {
- nsRefPtr<DOMFileImpl> lastBlob;
- rv = blobImpl->Slice(0, length, aContentType, 3,
- getter_AddRefs(lastBlob));
- NS_ENSURE_SUCCESS(rv, nullptr);
+ nsRefPtr<DOMFileImpl> lastBlobImpl =
+ blobImpl->CreateSlice(0, length, aContentType, aRv);
+ if (NS_WARN_IF(aRv.Failed())) {
+ return nullptr;
+ }
- blobImpls.AppendElement(lastBlob);
+ blobImpls.AppendElement(lastBlobImpl);
} else {
blobImpls.AppendElement(blobImpl);
}
length -= std::min<uint64_t>(l, length);
}
// we can create our blob now
nsRefPtr<DOMFileImpl> impl =
new DOMMultipartFileImpl(blobImpls, aContentType);
return impl.forget();
}
-/* static */ nsresult
-DOMMultipartFileImpl::NewFile(const nsAString& aName, nsISupports** aNewObject)
+void
+DOMMultipartFileImpl::InitializeBlob()
{
- nsCOMPtr<nsISupports> file =
- do_QueryObject(new DOMFile(new DOMMultipartFileImpl(aName)));
- file.forget(aNewObject);
- return NS_OK;
-}
-
-/* static */ nsresult
-DOMMultipartFileImpl::NewBlob(nsISupports** aNewObject)
-{
- nsCOMPtr<nsISupports> file =
- do_QueryObject(new DOMFile(new DOMMultipartFileImpl()));
- file.forget(aNewObject);
- return NS_OK;
+ SetLengthAndModifiedDate();
}
-static nsIDOMBlob*
-GetXPConnectNative(JSContext* aCx, JSObject* aObj) {
- nsCOMPtr<nsIDOMBlob> blob = do_QueryInterface(
- nsContentUtils::XPConnect()->GetNativeOfWrapper(aCx, aObj));
- return blob;
-}
-
-nsresult
-DOMMultipartFileImpl::Initialize(nsISupports* aOwner,
- JSContext* aCx,
- JSObject* aObj,
- const JS::CallArgs& aArgs)
+void
+DOMMultipartFileImpl::InitializeBlob(
+ JSContext* aCx,
+ const Sequence<OwningArrayBufferOrArrayBufferViewOrBlobOrString>& aData,
+ const nsAString& aContentType,
+ bool aNativeEOL,
+ ErrorResult& aRv)
{
- if (!mIsFile) {
- return InitBlob(aCx, aArgs.length(), aArgs.array(), GetXPConnectNative);
- }
+ mContentType = aContentType;
+ BlobSet blobSet;
+
+ for (uint32_t i = 0, len = aData.Length(); i < len; ++i) {
+ const OwningArrayBufferOrArrayBufferViewOrBlobOrString& data = aData[i];
- if (!nsContentUtils::IsCallerChrome()) {
- return InitFile(aCx, aArgs.length(), aArgs.array());
- }
+ if (data.IsBlob()) {
+ nsRefPtr<DOMFile> file = data.GetAsBlob().get();
+ blobSet.AppendBlobImpl(file->Impl());
+ }
+
+ else if (data.IsString()) {
+ aRv = blobSet.AppendString(data.GetAsString(), aNativeEOL, aCx);
+ if (aRv.Failed()) {
+ return;
+ }
+ }
- if (aArgs.length() > 0) {
- JS::Value* argv = aArgs.array();
- if (argv[0].isObject()) {
- JS::Rooted<JSObject*> obj(aCx, &argv[0].toObject());
- if (JS_IsArrayObject(aCx, obj)) {
- return InitFile(aCx, aArgs.length(), aArgs.array());
+ else if (data.IsArrayBuffer()) {
+ const ArrayBuffer& buffer = data.GetAsArrayBuffer();
+ buffer.ComputeLengthAndData();
+ aRv = blobSet.AppendVoidPtr(buffer.Data(), buffer.Length());
+ if (aRv.Failed()) {
+ return;
}
}
+
+ else if (data.IsArrayBufferView()) {
+ const ArrayBufferView& buffer = data.GetAsArrayBufferView();
+ buffer.ComputeLengthAndData();
+ aRv = blobSet.AppendVoidPtr(buffer.Data(), buffer.Length());
+ if (aRv.Failed()) {
+ return;
+ }
+ }
+
+ else {
+ MOZ_CRASH("Impossible blob data type.");
+ }
}
- return InitChromeFile(aCx, aArgs.length(), aArgs.array());
-}
-
-nsresult
-DOMMultipartFileImpl::InitBlob(JSContext* aCx,
- uint32_t aArgc,
- JS::Value* aArgv,
- UnwrapFuncPtr aUnwrapFunc)
-{
- bool nativeEOL = false;
- if (aArgc > 1) {
- BlobPropertyBag d;
- if (!d.Init(aCx, JS::Handle<JS::Value>::fromMarkedLocation(&aArgv[1]))) {
- return NS_ERROR_TYPE_ERR;
- }
- mContentType = d.mType;
- nativeEOL = d.mEndings == EndingTypes::Native;
- }
-
- if (aArgc > 0) {
- return ParseBlobArrayArgument(aCx, aArgv[0], nativeEOL, aUnwrapFunc);
- }
-
- SetLengthAndModifiedDate();
-
- return NS_OK;
-}
-
-nsresult
-DOMMultipartFileImpl::ParseBlobArrayArgument(JSContext* aCx, JS::Value& aValue,
- bool aNativeEOL,
- UnwrapFuncPtr aUnwrapFunc)
-{
- if (!aValue.isObject()) {
- return NS_ERROR_TYPE_ERR; // We're not interested
- }
-
- JS::Rooted<JSObject*> obj(aCx, &aValue.toObject());
- if (!JS_IsArrayObject(aCx, obj)) {
- return NS_ERROR_TYPE_ERR; // We're not interested
- }
-
- BlobSet blobSet;
-
- uint32_t length;
- MOZ_ALWAYS_TRUE(JS_GetArrayLength(aCx, obj, &length));
- for (uint32_t i = 0; i < length; ++i) {
- JS::Rooted<JS::Value> element(aCx);
- if (!JS_GetElement(aCx, obj, i, &element))
- return NS_ERROR_TYPE_ERR;
-
- if (element.isObject()) {
- JS::Rooted<JSObject*> obj(aCx, &element.toObject());
- nsCOMPtr<nsIDOMBlob> blob = aUnwrapFunc(aCx, obj);
- if (blob) {
- nsRefPtr<DOMFileImpl> blobImpl =
- static_cast<DOMFile*>(blob.get())->Impl();
-
- // Flatten so that multipart blobs will never nest
- const nsTArray<nsRefPtr<DOMFileImpl>>* subBlobImpls =
- blobImpl->GetSubBlobImpls();
- if (subBlobImpls) {
- blobSet.AppendBlobImpls(*subBlobImpls);
- } else {
- blobSet.AppendBlobImpl(blobImpl);
- }
- continue;
- }
- if (JS_IsArrayBufferViewObject(obj)) {
- nsresult rv = blobSet.AppendVoidPtr(
- JS_GetArrayBufferViewData(obj),
- JS_GetArrayBufferViewByteLength(obj));
- NS_ENSURE_SUCCESS(rv, rv);
- continue;
- }
- if (JS_IsArrayBufferObject(obj)) {
- nsresult rv = blobSet.AppendArrayBuffer(obj);
- NS_ENSURE_SUCCESS(rv, rv);
- continue;
- }
- }
-
- // coerce it to a string
- JSString* str = JS::ToString(aCx, element);
- NS_ENSURE_TRUE(str, NS_ERROR_TYPE_ERR);
-
- nsresult rv = blobSet.AppendString(str, aNativeEOL, aCx);
- NS_ENSURE_SUCCESS(rv, rv);
- }
mBlobImpls = blobSet.GetBlobImpls();
-
SetLengthAndModifiedDate();
-
- return NS_OK;
}
void
DOMMultipartFileImpl::SetLengthAndModifiedDate()
{
MOZ_ASSERT(mLength == UINT64_MAX);
MOZ_ASSERT(mLastModificationDate == UINT64_MAX);
@@ -279,184 +191,169 @@ DOMMultipartFileImpl::SetLengthAndModifi
for (uint32_t index = 0, count = mBlobImpls.Length(); index < count; index++) {
nsRefPtr<DOMFileImpl>& blob = mBlobImpls[index];
#ifdef DEBUG
MOZ_ASSERT(!blob->IsSizeUnknown());
MOZ_ASSERT(!blob->IsDateUnknown());
#endif
- uint64_t subBlobLength;
- MOZ_ALWAYS_TRUE(NS_SUCCEEDED(blob->GetSize(&subBlobLength)));
+ ErrorResult error;
+ uint64_t subBlobLength = blob->GetSize(error);
+ MOZ_ALWAYS_TRUE(!error.Failed());
MOZ_ASSERT(UINT64_MAX - subBlobLength >= totalLength);
totalLength += subBlobLength;
}
mLength = totalLength;
if (mIsFile) {
- mLastModificationDate = PR_Now();
+ // We cannot use PR_Now() because bug 493756 and, for this reason:
+ // var x = new Date(); var f = new File(...);
+ // x.getTime() < f.dateModified.getTime()
+ // could fail.
+ mLastModificationDate = JS_Now();
}
}
-nsresult
-DOMMultipartFileImpl::GetMozFullPathInternal(nsAString& aFilename)
+void
+DOMMultipartFileImpl::GetMozFullPathInternal(nsAString& aFilename,
+ ErrorResult& aRv)
{
- if (!mIsFromNsiFile || mBlobImpls.Length() == 0) {
- return DOMFileImplBase::GetMozFullPathInternal(aFilename);
+ if (!mIsFromNsIFile || mBlobImpls.Length() == 0) {
+ DOMFileImplBase::GetMozFullPathInternal(aFilename, aRv);
+ return;
}
DOMFileImpl* blobImpl = mBlobImpls.ElementAt(0).get();
if (!blobImpl) {
- return DOMFileImplBase::GetMozFullPathInternal(aFilename);
+ DOMFileImplBase::GetMozFullPathInternal(aFilename, aRv);
+ return;
}
- return blobImpl->GetMozFullPathInternal(aFilename);
+ blobImpl->GetMozFullPathInternal(aFilename, aRv);
}
-nsresult
-DOMMultipartFileImpl::InitChromeFile(JSContext* aCx,
- uint32_t aArgc,
- JS::Value* aArgv)
+void
+DOMMultipartFileImpl::InitializeChromeFile(DOMFile& aBlob,
+ const FilePropertyBag& aBag,
+ ErrorResult& aRv)
{
- nsresult rv;
+ NS_ASSERTION(!mImmutable, "Something went wrong ...");
- NS_ASSERTION(!mImmutable, "Something went wrong ...");
- NS_ENSURE_TRUE(!mImmutable, NS_ERROR_UNEXPECTED);
+ if (mImmutable) {
+ aRv.Throw(NS_ERROR_UNEXPECTED);
+ return;
+ }
+
MOZ_ASSERT(nsContentUtils::IsCallerChrome());
- NS_ENSURE_TRUE(aArgc > 0, NS_ERROR_UNEXPECTED);
- if (aArgc > 1) {
- FilePropertyBag d;
- if (!d.Init(aCx, JS::Handle<JS::Value>::fromMarkedLocation(&aArgv[1]))) {
- return NS_ERROR_TYPE_ERR;
- }
- mName = d.mName;
- mContentType = d.mType;
+ mName = aBag.mName;
+ mContentType = aBag.mType;
+ mIsFromNsIFile = true;
+
+ // XXXkhuey this is terrible
+ if (mContentType.IsEmpty()) {
+ aBlob.GetType(mContentType);
}
- // We expect to get a path to represent as a File object or
- // Blob object, an nsIFile, or an nsIDOMFile.
- nsCOMPtr<nsIFile> file;
- nsCOMPtr<nsIDOMBlob> blob;
- if (!aArgv[0].isString()) {
- // Lets see if it's an nsIFile
- if (!aArgv[0].isObject()) {
- return NS_ERROR_UNEXPECTED; // We're not interested
- }
+ BlobSet blobSet;
+ blobSet.AppendBlobImpl(aBlob.Impl());
+ mBlobImpls = blobSet.GetBlobImpls();
- JSObject* obj = &aArgv[0].toObject();
-
- nsISupports* supports =
- nsContentUtils::XPConnect()->GetNativeOfWrapper(aCx, obj);
- if (!supports) {
- return NS_ERROR_UNEXPECTED;
- }
+ SetLengthAndModifiedDate();
+}
- blob = do_QueryInterface(supports);
- file = do_QueryInterface(supports);
- if (!blob && !file) {
- return NS_ERROR_UNEXPECTED;
- }
+void
+DOMMultipartFileImpl::InitializeChromeFile(nsPIDOMWindow* aWindow,
+ nsIFile* aFile,
+ const FilePropertyBag& aBag,
+ bool aIsFromNsIFile,
+ ErrorResult& aRv)
+{
+ NS_ASSERTION(!mImmutable, "Something went wrong ...");
+ if (mImmutable) {
+ aRv.Throw(NS_ERROR_UNEXPECTED);
+ return;
+ }
- mIsFromNsiFile = true;
- } else {
- // It's a string
- JSString* str = JS::ToString(aCx, JS::Handle<JS::Value>::fromMarkedLocation(&aArgv[0]));
- NS_ENSURE_TRUE(str, NS_ERROR_XPC_BAD_CONVERT_JS);
+ MOZ_ASSERT(nsContentUtils::IsCallerChrome());
- nsAutoJSString xpcomStr;
- if (!xpcomStr.init(aCx, str)) {
- return NS_ERROR_XPC_BAD_CONVERT_JS;
- }
+ mName = aBag.mName;
+ mContentType = aBag.mType;
+ mIsFromNsIFile = aIsFromNsIFile;
- rv = NS_NewLocalFile(xpcomStr, false, getter_AddRefs(file));
- NS_ENSURE_SUCCESS(rv, rv);
+ bool exists;
+ aRv = aFile->Exists(&exists);
+ if (NS_WARN_IF(aRv.Failed())) {
+ return;
}
- if (file) {
- bool exists;
- rv = file->Exists(&exists);
- NS_ENSURE_SUCCESS(rv, rv);
- NS_ENSURE_TRUE(exists, NS_ERROR_FILE_NOT_FOUND);
+ if (!exists) {
+ aRv.Throw(NS_ERROR_FILE_NOT_FOUND);
+ return;
+ }
- bool isDir;
- rv = file->IsDirectory(&isDir);
- NS_ENSURE_SUCCESS(rv, rv);
- NS_ENSURE_FALSE(isDir, NS_ERROR_FILE_IS_DIRECTORY);
+ bool isDir;
+ aRv = aFile->IsDirectory(&isDir);
+ if (NS_WARN_IF(aRv.Failed())) {
+ return;
+ }
+
+ if (isDir) {
+ aRv.Throw(NS_ERROR_FILE_IS_DIRECTORY);
+ return;
+ }
- if (mName.IsEmpty()) {
- file->GetLeafName(mName);
- }
+ if (mName.IsEmpty()) {
+ aFile->GetLeafName(mName);
+ }
- nsRefPtr<DOMFile> domFile = DOMFile::CreateFromFile(file);
+ nsRefPtr<DOMFile> blob = DOMFile::CreateFromFile(aWindow, aFile);
- // Pre-cache size.
- uint64_t unused;
- rv = domFile->GetSize(&unused);
- NS_ENSURE_SUCCESS(rv, rv);
+ // Pre-cache size.
+ uint64_t unused;
+ aRv = blob->GetSize(&unused);
+ if (NS_WARN_IF(aRv.Failed())) {
+ return;
+ }
- // Pre-cache modified date.
- rv = domFile->GetMozLastModifiedDate(&unused);
- NS_ENSURE_SUCCESS(rv, rv);
-
- blob = domFile.forget();
+ // Pre-cache modified date.
+ aRv = blob->GetMozLastModifiedDate(&unused);
+ if (NS_WARN_IF(aRv.Failed())) {
+ return;
}
// XXXkhuey this is terrible
if (mContentType.IsEmpty()) {
blob->GetType(mContentType);
}
BlobSet blobSet;
blobSet.AppendBlobImpl(static_cast<DOMFile*>(blob.get())->Impl());
mBlobImpls = blobSet.GetBlobImpls();
SetLengthAndModifiedDate();
-
- return NS_OK;
}
-nsresult
-DOMMultipartFileImpl::InitFile(JSContext* aCx,
- uint32_t aArgc,
- JS::Value* aArgv)
+void
+DOMMultipartFileImpl::InitializeChromeFile(nsPIDOMWindow* aWindow,
+ const nsAString& aData,
+ const FilePropertyBag& aBag,
+ ErrorResult& aRv)
{
- NS_ASSERTION(!mImmutable, "Something went wrong ...");
- NS_ENSURE_TRUE(!mImmutable, NS_ERROR_UNEXPECTED);
-
- if (aArgc < 2) {
- return NS_ERROR_TYPE_ERR;
+ nsCOMPtr<nsIFile> file;
+ aRv = NS_NewLocalFile(aData, false, getter_AddRefs(file));
+ if (NS_WARN_IF(aRv.Failed())) {
+ return;
}
- // File name
- JSString* str = JS::ToString(aCx, JS::Handle<JS::Value>::fromMarkedLocation(&aArgv[1]));
- NS_ENSURE_TRUE(str, NS_ERROR_XPC_BAD_CONVERT_JS);
-
- nsAutoJSString xpcomStr;
- if (!xpcomStr.init(aCx, str)) {
- return NS_ERROR_XPC_BAD_CONVERT_JS;
- }
-
- mName = xpcomStr;
-
- // Optional params
- bool nativeEOL = false;
- if (aArgc > 2) {
- BlobPropertyBag d;
- if (!d.Init(aCx, JS::Handle<JS::Value>::fromMarkedLocation(&aArgv[2]))) {
- return NS_ERROR_TYPE_ERR;
- }
- mContentType = d.mType;
- nativeEOL = d.mEndings == EndingTypes::Native;
- }
-
- return ParseBlobArrayArgument(aCx, aArgv[0], nativeEOL, GetXPConnectNative);
+ InitializeChromeFile(aWindow, file, aBag, false, aRv);
}
nsresult
BlobSet::AppendVoidPtr(const void* aData, uint32_t aLength)
{
NS_ENSURE_ARG_POINTER(aData);
uint64_t offset = mDataLen;
@@ -464,26 +361,21 @@ BlobSet::AppendVoidPtr(const void* aData
if (!ExpandBufferSize(aLength))
return NS_ERROR_OUT_OF_MEMORY;
memcpy((char*)mData + offset, aData, aLength);
return NS_OK;
}
nsresult
-BlobSet::AppendString(JSString* aString, bool nativeEOL, JSContext* aCx)
+BlobSet::AppendString(const nsAString& aString, bool aNativeEOL, JSContext* aCx)
{
- nsAutoJSString xpcomStr;
- if (!xpcomStr.init(aCx, aString)) {
- return NS_ERROR_XPC_BAD_CONVERT_JS;
- }
+ NS_ConvertUTF16toUTF8 utf8Str(aString);
- nsCString utf8Str = NS_ConvertUTF16toUTF8(xpcomStr);
-
- if (nativeEOL) {
+ if (aNativeEOL) {
if (utf8Str.FindChar('\r') != kNotFound) {
utf8Str.ReplaceSubstring("\r\n", "\n");
utf8Str.ReplaceSubstring("\r", "\n");
}
#ifdef XP_WIN
utf8Str.ReplaceSubstring("\n", "\r\n");
#endif
}
@@ -506,15 +398,8 @@ BlobSet::AppendBlobImpl(DOMFileImpl* aBl
nsresult
BlobSet::AppendBlobImpls(const nsTArray<nsRefPtr<DOMFileImpl>>& aBlobImpls)
{
Flush();
mBlobImpls.AppendElements(aBlobImpls);
return NS_OK;
}
-
-nsresult
-BlobSet::AppendArrayBuffer(JSObject* aBuffer)
-{
- return AppendVoidPtr(JS_GetArrayBufferData(aBuffer),
- JS_GetArrayBufferByteLength(aBuffer));
-}
--- a/content/base/src/nsDOMBlobBuilder.h
+++ b/content/base/src/nsDOMBlobBuilder.h
@@ -3,150 +3,151 @@
* 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/. */
#ifndef nsDOMBlobBuilder_h
#define nsDOMBlobBuilder_h
#include "nsDOMFile.h"
+#include "mozilla/Attributes.h"
#include "mozilla/CheckedInt.h"
-#include "mozilla/Attributes.h"
+#include "mozilla/ErrorResult.h"
+#include "mozilla/dom/BlobBinding.h"
+#include "mozilla/dom/FileBinding.h"
#include <algorithm>
-#define NS_DOMMULTIPARTBLOB_CID { 0x47bf0b43, 0xf37e, 0x49ef, \
- { 0x81, 0xa0, 0x18, 0xba, 0xc0, 0x57, 0xb5, 0xcc } }
-#define NS_DOMMULTIPARTBLOB_CONTRACTID "@mozilla.org/dom/multipart-blob;1"
-
-#define NS_DOMMULTIPARTFILE_CID { 0xc3361f77, 0x60d1, 0x4ea9, \
- { 0x94, 0x96, 0xdf, 0x5d, 0x6f, 0xcd, 0xd7, 0x8f } }
-#define NS_DOMMULTIPARTFILE_CONTRACTID "@mozilla.org/dom/multipart-file;1"
-
+using namespace mozilla;
using namespace mozilla::dom;
class DOMMultipartFileImpl MOZ_FINAL : public DOMFileImplBase
{
public:
NS_DECL_ISUPPORTS_INHERITED
// Create as a file
DOMMultipartFileImpl(const nsTArray<nsRefPtr<DOMFileImpl>>& aBlobImpls,
const nsAString& aName,
const nsAString& aContentType)
: DOMFileImplBase(aName, aContentType, UINT64_MAX),
mBlobImpls(aBlobImpls),
- mIsFromNsiFile(false)
+ mIsFromNsIFile(false)
{
SetLengthAndModifiedDate();
}
// Create as a blob
DOMMultipartFileImpl(const nsTArray<nsRefPtr<DOMFileImpl>>& aBlobImpls,
const nsAString& aContentType)
: DOMFileImplBase(aContentType, UINT64_MAX),
mBlobImpls(aBlobImpls),
- mIsFromNsiFile(false)
+ mIsFromNsIFile(false)
{
SetLengthAndModifiedDate();
}
// Create as a file to be later initialized
explicit DOMMultipartFileImpl(const nsAString& aName)
: DOMFileImplBase(aName, EmptyString(), UINT64_MAX),
- mIsFromNsiFile(false)
+ mIsFromNsIFile(false)
{
}
// Create as a blob to be later initialized
DOMMultipartFileImpl()
: DOMFileImplBase(EmptyString(), UINT64_MAX),
- mIsFromNsiFile(false)
+ mIsFromNsIFile(false)
{
}
- virtual nsresult
- Initialize(nsISupports* aOwner, JSContext* aCx, JSObject* aObj,
- const JS::CallArgs& aArgs) MOZ_OVERRIDE;
+ void InitializeBlob();
+
+ void InitializeBlob(
+ JSContext* aCx,
+ const Sequence<OwningArrayBufferOrArrayBufferViewOrBlobOrString>& aData,
+ const nsAString& aContentType,
+ bool aNativeEOL,
+ ErrorResult& aRv);
- typedef nsIDOMBlob* (*UnwrapFuncPtr)(JSContext*, JSObject*);
- nsresult InitBlob(JSContext* aCx,
- uint32_t aArgc,
- JS::Value* aArgv,
- UnwrapFuncPtr aUnwrapFunc);
- nsresult InitFile(JSContext* aCx,
- uint32_t aArgc,
- JS::Value* aArgv);
- nsresult InitChromeFile(JSContext* aCx,
- uint32_t aArgc,
- JS::Value* aArgv);
+ void InitializeChromeFile(DOMFile& aData,
+ const FilePropertyBag& aBag,
+ ErrorResult& aRv);
+
+ void InitializeChromeFile(nsPIDOMWindow* aWindow,
+ const nsAString& aData,
+ const FilePropertyBag& aBag,
+ ErrorResult& aRv);
+
+ void InitializeChromeFile(nsPIDOMWindow* aWindow,
+ nsIFile* aData,
+ const FilePropertyBag& aBag,
+ bool aIsFromNsIFile,
+ ErrorResult& aRv);
virtual already_AddRefed<DOMFileImpl>
CreateSlice(uint64_t aStart, uint64_t aLength,
- const nsAString& aContentType) MOZ_OVERRIDE;
+ const nsAString& aContentType,
+ ErrorResult& aRv) MOZ_OVERRIDE;
- virtual nsresult GetSize(uint64_t* aSize) MOZ_OVERRIDE;
+ virtual uint64_t GetSize(ErrorResult& aRv) MOZ_OVERRIDE
+ {
+ return mLength;
+ }
virtual nsresult GetInternalStream(nsIInputStream** aInputStream) MOZ_OVERRIDE;
- 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<nsRefPtr<DOMFileImpl>>* GetSubBlobImpls() const MOZ_OVERRIDE
{
return &mBlobImpls;
}
- virtual nsresult GetMozFullPathInternal(nsAString& aFullPath) MOZ_OVERRIDE;
+ virtual void GetMozFullPathInternal(nsAString& aFullPath,
+ ErrorResult& aRv) MOZ_OVERRIDE;
+
+ void SetName(const nsAString& aName)
+ {
+ mName = aName;
+ }
+
+ void SetFromNsIFile(bool aValue)
+ {
+ mIsFromNsIFile = aValue;
+ }
protected:
virtual ~DOMMultipartFileImpl() {}
- nsresult ParseBlobArrayArgument(JSContext* aCx, JS::Value& aValue,
- bool aNativeEOL, UnwrapFuncPtr aUnwrapFunc);
-
void SetLengthAndModifiedDate();
nsTArray<nsRefPtr<DOMFileImpl>> mBlobImpls;
- bool mIsFromNsiFile;
+ bool mIsFromNsIFile;
};
class BlobSet {
public:
BlobSet()
: mData(nullptr), mDataLen(0), mDataBufferLen(0)
{}
~BlobSet()
{
moz_free(mData);
}
nsresult AppendVoidPtr(const void* aData, uint32_t aLength);
- nsresult AppendString(JSString* aString, bool nativeEOL, JSContext* aCx);
+ nsresult AppendString(const nsAString& aString, bool nativeEOL, JSContext* aCx);
nsresult AppendBlobImpl(DOMFileImpl* aBlobImpl);
- nsresult AppendArrayBuffer(JSObject* aBuffer);
nsresult AppendBlobImpls(const nsTArray<nsRefPtr<DOMFileImpl>>& aBlobImpls);
nsTArray<nsRefPtr<DOMFileImpl>>& GetBlobImpls() { Flush(); return mBlobImpls; }
- already_AddRefed<nsIDOMBlob>
- GetBlobInternal(const nsACString& aContentType)
+ already_AddRefed<DOMFile>
+ GetBlobInternal(nsISupports* aParent, const nsACString& aContentType)
{
- nsCOMPtr<nsIDOMBlob> blob = new DOMFile(
+ nsRefPtr<DOMFile> blob = new DOMFile(aParent,
new DOMMultipartFileImpl(GetBlobImpls(), NS_ConvertASCIItoUTF16(aContentType)));
return blob.forget();
}
protected:
bool ExpandBufferSize(uint64_t aSize)
{
using mozilla::CheckedUint32;
--- a/content/base/src/nsDOMDataChannel.cpp
+++ b/content/base/src/nsDOMDataChannel.cpp
@@ -17,17 +17,17 @@
extern PRLogModuleInfo* GetDataChannelLog();
#endif
#undef LOG
#define LOG(args) PR_LOG(GetDataChannelLog(), PR_LOG_DEBUG, args)
#include "nsDOMDataChannelDeclarations.h"
#include "nsDOMDataChannel.h"
-#include "nsIDOMFile.h"
+#include "nsDOMFile.h"
#include "nsIDOMDataChannel.h"
#include "nsIDOMMessageEvent.h"
#include "mozilla/DOMEventTargetHelper.h"
#include "mozilla/dom/ScriptSettings.h"
#include "nsError.h"
#include "nsAutoPtr.h"
#include "nsContentUtils.h"
@@ -267,29 +267,29 @@ nsDOMDataChannel::Close()
void
nsDOMDataChannel::Send(const nsAString& aData, ErrorResult& aRv)
{
NS_ConvertUTF16toUTF8 msgString(aData);
Send(nullptr, msgString, msgString.Length(), false, aRv);
}
void
-nsDOMDataChannel::Send(nsIDOMBlob* aData, ErrorResult& aRv)
+nsDOMDataChannel::Send(DOMFile& aData, ErrorResult& aRv)
{
NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
nsCOMPtr<nsIInputStream> msgStream;
- nsresult rv = aData->GetInternalStream(getter_AddRefs(msgStream));
+ nsresult rv = aData.GetInternalStream(getter_AddRefs(msgStream));
if (NS_FAILED(rv)) {
aRv.Throw(rv);
return;
}
uint64_t msgLength;
- rv = aData->GetSize(&msgLength);
+ rv = aData.GetSize(&msgLength);
if (NS_FAILED(rv)) {
aRv.Throw(rv);
return;
}
if (msgLength > UINT32_MAX) {
aRv.Throw(NS_ERROR_FILE_TOO_BIG);
return;
@@ -388,17 +388,17 @@ nsDOMDataChannel::DoOnMessageAvailable(c
return NS_ERROR_FAILURE;
}
JSContext* cx = jsapi.cx();
JS::Rooted<JS::Value> jsData(cx);
if (aBinary) {
if (mBinaryType == DC_BINARY_TYPE_BLOB) {
- rv = nsContentUtils::CreateBlobBuffer(cx, aData, &jsData);
+ rv = nsContentUtils::CreateBlobBuffer(cx, GetOwner(), aData, &jsData);
NS_ENSURE_SUCCESS(rv, rv);
} else if (mBinaryType == DC_BINARY_TYPE_ARRAYBUFFER) {
JS::Rooted<JSObject*> arrayBuf(cx);
rv = nsContentUtils::CreateArrayBuffer(cx, aData, arrayBuf.address());
NS_ENSURE_SUCCESS(rv, rv);
jsData = OBJECT_TO_JSVAL(arrayBuf);
} else {
NS_RUNTIMEABORT("Unknown binary type!");
--- a/content/base/src/nsDOMDataChannel.h
+++ b/content/base/src/nsDOMDataChannel.h
@@ -12,16 +12,20 @@
#include "mozilla/dom/DataChannelBinding.h"
#include "mozilla/dom/TypedArray.h"
#include "mozilla/net/DataChannelListener.h"
#include "nsIDOMDataChannel.h"
#include "nsIInputStream.h"
namespace mozilla {
+namespace dom {
+class DOMFile;
+}
+
class DataChannel;
};
class nsDOMDataChannel : public mozilla::DOMEventTargetHelper,
public nsIDOMDataChannel,
public mozilla::DataChannelListener
{
public:
@@ -61,17 +65,17 @@ public:
static_cast<int>(mBinaryType));
}
void SetBinaryType(mozilla::dom::RTCDataChannelType aType)
{
mBinaryType = static_cast<DataChannelBinaryType>(
static_cast<int>(aType));
}
void Send(const nsAString& aData, mozilla::ErrorResult& aRv);
- void Send(nsIDOMBlob* aData, mozilla::ErrorResult& aRv);
+ void Send(mozilla::dom::DOMFile& aData, mozilla::ErrorResult& aRv);
void Send(const mozilla::dom::ArrayBuffer& aData, mozilla::ErrorResult& aRv);
void Send(const mozilla::dom::ArrayBufferView& aData,
mozilla::ErrorResult& aRv);
// Uses XPIDL GetProtocol.
bool Ordered() const;
uint16_t Id() const;
uint16_t Stream() const; // deprecated
--- a/content/base/src/nsDOMFile.cpp
+++ b/content/base/src/nsDOMFile.cpp
@@ -4,20 +4,19 @@
* 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 "nsDOMFile.h"
#include "nsCExternalHandlerService.h"
#include "nsContentCID.h"
#include "nsContentUtils.h"
-#include "nsDOMClassInfoID.h"
+#include "nsDOMBlobBuilder.h"
#include "nsError.h"
#include "nsICharsetDetector.h"
-#include "nsIClassInfo.h"
#include "nsIConverterInputStream.h"
#include "nsIDocument.h"
#include "nsIFileStreams.h"
#include "nsIInputStream.h"
#include "nsIIPCSerializableInputStream.h"
#include "nsIMemoryReporter.h"
#include "nsIMIMEService.h"
#include "nsISeekableStream.h"
@@ -30,23 +29,24 @@
#include "nsHostObjectProtocolHandler.h"
#include "nsStringStream.h"
#include "nsJSUtils.h"
#include "nsPrintfCString.h"
#include "mozilla/SHA1.h"
#include "mozilla/CheckedInt.h"
#include "mozilla/Preferences.h"
#include "mozilla/Attributes.h"
+#include "mozilla/dom/BlobBinding.h"
+#include "mozilla/dom/DOMError.h"
+#include "mozilla/dom/FileBinding.h"
+#include "mozilla/dom/WorkerPrivate.h"
#include "nsThreadUtils.h"
#include "mozilla/dom/FileListBinding.h"
-DOMCI_DATA(File, mozilla::dom::DOMFile)
-DOMCI_DATA(Blob, mozilla::dom::DOMFile)
-
namespace mozilla {
namespace dom {
// XXXkhuey the input stream that we pass out of a DOMFile
// can outlive the actual DOMFile object. Thus, we must
// ensure that the buffer underlying the stream we get
// from NS_NewByteInputStream is held alive as long as the
// stream is. We do that by passing back this class instead.
@@ -125,150 +125,178 @@ nsresult DataOwnerAdapter::Create(DataOw
////////////////////////////////////////////////////////////////////////////
// mozilla::dom::DOMFile implementation
NS_IMPL_CYCLE_COLLECTION_CLASS(DOMFile)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(DOMFile)
MOZ_ASSERT(tmp->mImpl);
tmp->mImpl->Unlink();
+ NS_IMPL_CYCLE_COLLECTION_UNLINK(mParent)
+ NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(DOMFile)
MOZ_ASSERT(tmp->mImpl);
tmp->mImpl->Traverse(cb);
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParent)
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(DOMFile)
+ NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
+NS_IMPL_CYCLE_COLLECTION_TRACE_END
+
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DOMFile)
// This class should not receive any nsIRemoteBlob QI!
MOZ_ASSERT(!aIID.Equals(NS_GET_IID(nsIRemoteBlob)));
+ NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMFile)
NS_INTERFACE_MAP_ENTRY(nsIDOMBlob)
NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIDOMFile, IsFile())
NS_INTERFACE_MAP_ENTRY(nsIXHRSendable)
NS_INTERFACE_MAP_ENTRY(nsIMutable)
- NS_INTERFACE_MAP_ENTRY(nsIJSNativeInitializer)
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
- NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO_CONDITIONAL(File, IsFile())
- NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO_CONDITIONAL(Blob, !(IsFile()))
NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTING_ADDREF(DOMFile)
NS_IMPL_CYCLE_COLLECTING_RELEASE(DOMFile)
/* static */ already_AddRefed<DOMFile>
-DOMFile::Create(const nsAString& aName, const nsAString& aContentType,
- uint64_t aLength, uint64_t aLastModifiedDate)
+DOMFile::Create(nsISupports* aParent, const nsAString& aName,
+ const nsAString& aContentType, uint64_t aLength,
+ uint64_t aLastModifiedDate)
{
- nsRefPtr<DOMFile> file = new DOMFile(
+ nsRefPtr<DOMFile> file = new DOMFile(aParent,
new DOMFileImplBase(aName, aContentType, aLength, aLastModifiedDate));
return file.forget();
}
/* static */ already_AddRefed<DOMFile>
-DOMFile::Create(const nsAString& aName, const nsAString& aContentType,
- uint64_t aLength)
+DOMFile::Create(nsISupports* aParent, const nsAString& aName,
+ const nsAString& aContentType, uint64_t aLength)
{
- nsRefPtr<DOMFile> file = new DOMFile(
+ nsRefPtr<DOMFile> file = new DOMFile(aParent,
new DOMFileImplBase(aName, aContentType, aLength));
return file.forget();
}
/* static */ already_AddRefed<DOMFile>
-DOMFile::Create(const nsAString& aContentType, uint64_t aLength)
+DOMFile::Create(nsISupports* aParent, const nsAString& aContentType,
+ uint64_t aLength)
{
- nsRefPtr<DOMFile> file = new DOMFile(
+ nsRefPtr<DOMFile> file = new DOMFile(aParent,
new DOMFileImplBase(aContentType, aLength));
return file.forget();
}
/* static */ already_AddRefed<DOMFile>
-DOMFile::Create(const nsAString& aContentType, uint64_t aStart,
- uint64_t aLength)
+DOMFile::Create(nsISupports* aParent, const nsAString& aContentType,
+ uint64_t aStart, uint64_t aLength)
{
- nsRefPtr<DOMFile> file = new DOMFile(
+ nsRefPtr<DOMFile> file = new DOMFile(aParent,
new DOMFileImplBase(aContentType, aStart, aLength));
return file.forget();
}
/* static */ already_AddRefed<DOMFile>
-DOMFile::CreateMemoryFile(void* aMemoryBuffer, uint64_t aLength,
- const nsAString& aName,
+DOMFile::CreateMemoryFile(nsISupports* aParent, void* aMemoryBuffer,
+ uint64_t aLength, const nsAString& aName,
const nsAString& aContentType,
uint64_t aLastModifiedDate)
{
- nsRefPtr<DOMFile> file = new DOMFile(
+ nsRefPtr<DOMFile> file = new DOMFile(aParent,
new DOMFileImplMemory(aMemoryBuffer, aLength, aName,
aContentType, aLastModifiedDate));
return file.forget();
}
/* static */ already_AddRefed<DOMFile>
-DOMFile::CreateMemoryFile(void* aMemoryBuffer, uint64_t aLength,
- const nsAString& aContentType)
+DOMFile::CreateMemoryFile(nsISupports* aParent, void* aMemoryBuffer,
+ uint64_t aLength, const nsAString& aContentType)
{
- nsRefPtr<DOMFile> file = new DOMFile(
+ nsRefPtr<DOMFile> file = new DOMFile(aParent,
new DOMFileImplMemory(aMemoryBuffer, aLength, aContentType));
return file.forget();
}
/* static */ already_AddRefed<DOMFile>
-DOMFile::CreateTemporaryFileBlob(PRFileDesc* aFD, uint64_t aStartPos,
- uint64_t aLength,
- const nsAString& aContentType)
+DOMFile::CreateTemporaryFileBlob(nsISupports* aParent, PRFileDesc* aFD,
+ uint64_t aStartPos, uint64_t aLength,
+ const nsAString& aContentType)
{
- nsRefPtr<DOMFile> file = new DOMFile(
+ nsRefPtr<DOMFile> file = new DOMFile(aParent,
new DOMFileImplTemporaryFileBlob(aFD, aStartPos, aLength, aContentType));
return file.forget();
}
/* static */ already_AddRefed<DOMFile>
-DOMFile::CreateFromFile(nsIFile* aFile)
+DOMFile::CreateFromFile(nsISupports* aParent, nsIFile* aFile)
{
- nsRefPtr<DOMFile> file = new DOMFile(new DOMFileImplFile(aFile));
+ nsRefPtr<DOMFile> file = new DOMFile(aParent, new DOMFileImplFile(aFile));
return file.forget();
}
/* static */ already_AddRefed<DOMFile>
-DOMFile::CreateFromFile(const nsAString& aContentType, uint64_t aLength,
- nsIFile* aFile, indexedDB::FileInfo* aFileInfo)
+DOMFile::CreateFromFile(nsISupports* aParent, const nsAString& aContentType,
+ uint64_t aLength, nsIFile* aFile,
+ indexedDB::FileInfo* aFileInfo)
{
- nsRefPtr<DOMFile> file = new DOMFile(
+ nsRefPtr<DOMFile> file = new DOMFile(aParent,
new DOMFileImplFile(aContentType, aLength, aFile, aFileInfo));
return file.forget();
}
/* static */ already_AddRefed<DOMFile>
-DOMFile::CreateFromFile(const nsAString& aName,
+DOMFile::CreateFromFile(nsISupports* aParent, const nsAString& aName,
const nsAString& aContentType,
uint64_t aLength, nsIFile* aFile,
indexedDB::FileInfo* aFileInfo)
{
- nsRefPtr<DOMFile> file = new DOMFile(
+ nsRefPtr<DOMFile> file = new DOMFile(aParent,
new DOMFileImplFile(aName, aContentType, aLength, aFile, aFileInfo));
return file.forget();
}
/* static */ already_AddRefed<DOMFile>
-DOMFile::CreateFromFile(nsIFile* aFile, indexedDB::FileInfo* aFileInfo)
+DOMFile::CreateFromFile(nsISupports* aParent, nsIFile* aFile,
+ indexedDB::FileInfo* aFileInfo)
{
- nsRefPtr<DOMFile> file = new DOMFile(new DOMFileImplFile(aFile, aFileInfo));
+ nsRefPtr<DOMFile> file = new DOMFile(aParent,
+ new DOMFileImplFile(aFile, aFileInfo));
return file.forget();
}
/* static */ already_AddRefed<DOMFile>
-DOMFile::CreateFromFile(nsIFile* aFile, const nsAString& aName,
- const nsAString& aContentType)
+DOMFile::CreateFromFile(nsISupports* aParent, nsIFile* aFile,
+ const nsAString& aName, const nsAString& aContentType)
{
- nsRefPtr<DOMFile> file = new DOMFile(
+ nsRefPtr<DOMFile> file = new DOMFile(aParent,
new DOMFileImplFile(aFile, aName, aContentType));
return file.forget();
}
+DOMFile::DOMFile(nsISupports* aParent, DOMFileImpl* aImpl)
+ : mImpl(aImpl)
+ , mParent(aParent)
+{
+ MOZ_ASSERT(mImpl);
+ SetIsDOMBinding();
+
+#ifdef DEBUG
+ {
+ nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(aParent);
+ if (win) {
+ MOZ_ASSERT(win->IsInnerWindow());
+ }
+ }
+#endif
+}
+
const nsTArray<nsRefPtr<DOMFileImpl>>*
DOMFile::GetSubBlobImpls() const
{
return mImpl->GetSubBlobImpls();
}
bool
DOMFile::IsSizeUnknown() const
@@ -290,80 +318,131 @@ DOMFile::IsFile() const
void
DOMFile::SetLazyData(const nsAString& aName, const nsAString& aContentType,
uint64_t aLength, uint64_t aLastModifiedDate)
{
return mImpl->SetLazyData(aName, aContentType, aLength, aLastModifiedDate);
}
-already_AddRefed<nsIDOMBlob>
+already_AddRefed<DOMFile>
DOMFile::CreateSlice(uint64_t aStart, uint64_t aLength,
- const nsAString& aContentType)
+ const nsAString& aContentType,
+ ErrorResult& aRv)
{
- nsRefPtr<DOMFileImpl> impl =
- mImpl->CreateSlice(aStart, aLength, aContentType);
- nsRefPtr<DOMFile> slice = new DOMFile(impl);
- return slice.forget();
-}
+ nsRefPtr<DOMFileImpl> impl = mImpl->CreateSlice(aStart, aLength,
+ aContentType, aRv);
+ if (aRv.Failed()) {
+ return nullptr;
+ }
-NS_IMETHODIMP
-DOMFile::Initialize(nsISupports* aOwner, JSContext* aCx, JSObject* aObj,
- const JS::CallArgs& aArgs)
-{
- return mImpl->Initialize(aOwner, aCx, aObj, aArgs);
+ nsRefPtr<DOMFile> file = new DOMFile(mParent, impl);
+ return file.forget();
}
NS_IMETHODIMP
DOMFile::GetName(nsAString& aFileName)
{
- return mImpl->GetName(aFileName);
+ mImpl->GetName(aFileName);
+ return NS_OK;
}
NS_IMETHODIMP
DOMFile::GetPath(nsAString& aPath)
{
return mImpl->GetPath(aPath);
}
NS_IMETHODIMP
DOMFile::GetLastModifiedDate(JSContext* aCx,
JS::MutableHandle<JS::Value> aDate)
{
- return mImpl->GetLastModifiedDate(aCx, aDate);
+ ErrorResult rv;
+ Date value = GetLastModifiedDate(rv);
+ if (rv.Failed()) {
+ return rv.ErrorCode();
+ }
+
+ if (!value.ToDateObject(aCx, aDate)) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ return NS_OK;
+}
+
+Date
+DOMFile::GetLastModifiedDate(ErrorResult& aRv)
+{
+ int64_t value = GetLastModified(aRv);
+ if (aRv.Failed()) {
+ return Date();
+ }
+
+ return Date(value);
+}
+
+int64_t
+DOMFile::GetLastModified(ErrorResult& aRv)
+{
+ return mImpl->GetLastModified(aRv);
}
NS_IMETHODIMP
-DOMFile::GetMozFullPath(nsAString &aFileName)
+DOMFile::GetMozFullPath(nsAString& aFileName)
{
- return mImpl->GetMozFullPath(aFileName);
+ ErrorResult rv;
+ GetMozFullPath(aFileName, rv);
+ return rv.ErrorCode();
+}
+
+void
+DOMFile::GetMozFullPath(nsAString& aFilename, ErrorResult& aRv)
+{
+ mImpl->GetMozFullPath(aFilename, aRv);
}
NS_IMETHODIMP
-DOMFile::GetMozFullPathInternal(nsAString &aFileName)
+DOMFile::GetMozFullPathInternal(nsAString& aFileName)
{
- return mImpl->GetMozFullPathInternal(aFileName);
+ ErrorResult rv;
+ mImpl->GetMozFullPathInternal(aFileName, rv);
+ return rv.ErrorCode();
}
NS_IMETHODIMP
DOMFile::GetSize(uint64_t* aSize)
{
- return mImpl->GetSize(aSize);
+ MOZ_ASSERT(aSize);
+
+ ErrorResult rv;
+ *aSize = GetSize(rv);
+ return rv.ErrorCode();
+}
+
+uint64_t
+DOMFile::GetSize(ErrorResult& aRv)
+{
+ return mImpl->GetSize(aRv);
}
NS_IMETHODIMP
DOMFile::GetType(nsAString &aType)
{
- return mImpl->GetType(aType);
+ mImpl->GetType(aType);
+ return NS_OK;
}
NS_IMETHODIMP
DOMFile::GetMozLastModifiedDate(uint64_t* aDate)
{
- return mImpl->GetMozLastModifiedDate(aDate);
+ MOZ_ASSERT(aDate);
+
+ ErrorResult rv;
+ *aDate = GetLastModified(rv);
+ return rv.ErrorCode();
}
// Makes sure that aStart and aEnd is less then or equal to aSize and greater
// than 0
static void
ParseSize(int64_t aSize, int64_t& aStart, int64_t& aEnd)
{
CheckedInt64 newStartOffset = aStart;
@@ -398,28 +477,50 @@ ParseSize(int64_t aSize, int64_t& aStart
}
}
NS_IMETHODIMP
DOMFile::Slice(int64_t aStart, int64_t aEnd,
const nsAString& aContentType, uint8_t aArgc,
nsIDOMBlob **aBlob)
{
- MOZ_ASSERT(mImpl);
- nsRefPtr<DOMFileImpl> impl;
- nsresult rv = mImpl->Slice(aStart, aEnd, aContentType, aArgc,
- getter_AddRefs(impl));
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return rv;
+ Optional<int64_t> start;
+ if (aArgc > 0) {
+ start.Construct(aStart);
+ }
+
+ Optional<int64_t> end;
+ if (aArgc > 1) {
+ end.Construct(aEnd);
+ }
+
+ ErrorResult rv;
+ nsRefPtr<DOMFile> file = Slice(start, end, aContentType, rv);
+ if (rv.Failed()) {
+ return rv.ErrorCode();
}
- nsRefPtr<DOMFile> blob = new DOMFile(impl);
- blob.forget(aBlob);
+ file.forget(aBlob);
+ return NS_OK;
+}
- return NS_OK;
+already_AddRefed<DOMFile>
+DOMFile::Slice(const Optional<int64_t>& aStart,
+ const Optional<int64_t>& aEnd,
+ const nsAString& aContentType,
+ ErrorResult& aRv)
+{
+ nsRefPtr<DOMFileImpl> impl =
+ mImpl->Slice(aStart, aEnd, aContentType, aRv);
+ if (aRv.Failed()) {
+ return nullptr;
+ }
+
+ nsRefPtr<DOMFile> file = new DOMFile(mParent, impl);
+ return file.forget();
}
NS_IMETHODIMP
DOMFile::GetInternalStream(nsIInputStream** aStream)
{
return mImpl->GetInternalStream(aStream);
}
@@ -463,151 +564,244 @@ DOMFile::SetMutable(bool aMutable)
}
NS_IMETHODIMP_(bool)
DOMFile::IsMemoryFile()
{
return mImpl->IsMemoryFile();
}
+JSObject*
+DOMFile::WrapObject(JSContext* aCx)
+{
+ return IsFile() ? FileBinding::Wrap(aCx, this)
+ : BlobBinding::Wrap(aCx, this);
+}
+
+/* static */ already_AddRefed<DOMFile>
+DOMFile::Constructor(const GlobalObject& aGlobal, ErrorResult& aRv)
+{
+ nsRefPtr<DOMMultipartFileImpl> impl = new DOMMultipartFileImpl();
+
+ impl->InitializeBlob();
+ MOZ_ASSERT(!impl->IsFile());
+
+ nsRefPtr<DOMFile> file = new DOMFile(aGlobal.GetAsSupports(), impl);
+ return file.forget();
+}
+
+/* static */ already_AddRefed<DOMFile>
+DOMFile::Constructor(
+ const GlobalObject& aGlobal,
+ const Sequence<OwningArrayBufferOrArrayBufferViewOrBlobOrString>& aData,
+ const BlobPropertyBag& aBag,
+ ErrorResult& aRv)
+{
+ nsRefPtr<DOMMultipartFileImpl> impl = new DOMMultipartFileImpl();
+
+ impl->InitializeBlob(aGlobal.Context(), aData, aBag.mType,
+ aBag.mEndings == EndingTypes::Native, aRv);
+ if (aRv.Failed()) {
+ return nullptr;
+ }
+ MOZ_ASSERT(!impl->IsFile());
+
+ nsRefPtr<DOMFile> file = new DOMFile(aGlobal.GetAsSupports(), impl);
+ return file.forget();
+}
+
+/* static */ already_AddRefed<DOMFile>
+DOMFile::Constructor(
+ const GlobalObject& aGlobal,
+ const Sequence<OwningArrayBufferOrArrayBufferViewOrBlobOrString>& aData,
+ const nsAString& aName,
+ const FilePropertyBag& aBag,
+ ErrorResult& aRv)
+{
+ nsRefPtr<DOMMultipartFileImpl> impl = new DOMMultipartFileImpl(aName);
+
+ impl->InitializeBlob(aGlobal.Context(), aData, aBag.mType, false, aRv);
+ if (aRv.Failed()) {
+ return nullptr;
+ }
+ MOZ_ASSERT(impl->IsFile());
+
+ nsRefPtr<DOMFile> file = new DOMFile(aGlobal.GetAsSupports(), impl);
+ return file.forget();
+}
+
+/* static */ already_AddRefed<DOMFile>
+DOMFile::Constructor(const GlobalObject& aGlobal,
+ DOMFile& aData,
+ const FilePropertyBag& aBag,
+ ErrorResult& aRv)
+{
+ if (!nsContentUtils::IsCallerChrome()) {
+ aRv.Throw(NS_ERROR_FAILURE);
+ return nullptr;
+ }
+
+ nsRefPtr<DOMMultipartFileImpl> impl = new DOMMultipartFileImpl(EmptyString());
+ impl->InitializeChromeFile(aData, aBag, aRv);
+ if (aRv.Failed()) {
+ return nullptr;
+ }
+ MOZ_ASSERT(impl->IsFile());
+
+ nsRefPtr<DOMFile> domFile = new DOMFile(aGlobal.GetAsSupports(), impl);
+ return domFile.forget();
+}
+
+/* static */ already_AddRefed<DOMFile>
+DOMFile::Constructor(const GlobalObject& aGlobal,
+ nsIFile* aData,
+ const FilePropertyBag& aBag,
+ ErrorResult& aRv)
+{
+ if (!nsContentUtils::IsCallerChrome()) {
+ aRv.Throw(NS_ERROR_FAILURE);
+ return nullptr;
+ }
+
+ nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aGlobal.GetAsSupports());
+
+ nsRefPtr<DOMMultipartFileImpl> impl = new DOMMultipartFileImpl(EmptyString());
+ impl->InitializeChromeFile(window, aData, aBag, true, aRv);
+ if (aRv.Failed()) {
+ return nullptr;
+ }
+ MOZ_ASSERT(impl->IsFile());
+
+ nsRefPtr<DOMFile> domFile = new DOMFile(aGlobal.GetAsSupports(), impl);
+ return domFile.forget();
+}
+
+/* static */ already_AddRefed<DOMFile>
+DOMFile::Constructor(const GlobalObject& aGlobal,
+ const nsAString& aData,
+ const FilePropertyBag& aBag,
+ ErrorResult& aRv)
+{
+ if (!nsContentUtils::IsCallerChrome()) {
+ aRv.Throw(NS_ERROR_FAILURE);
+ return nullptr;
+ }
+
+ nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aGlobal.GetAsSupports());
+
+ nsRefPtr<DOMMultipartFileImpl> impl = new DOMMultipartFileImpl(EmptyString());
+ impl->InitializeChromeFile(window, aData, aBag, aRv);
+ if (aRv.Failed()) {
+ return nullptr;
+ }
+ MOZ_ASSERT(impl->IsFile());
+
+ nsRefPtr<DOMFile> domFile = new DOMFile(aGlobal.GetAsSupports(), impl);
+ return domFile.forget();
+}
+
////////////////////////////////////////////////////////////////////////////
// mozilla::dom::DOMFileImpl implementation
-nsresult
-DOMFileImpl::Slice(int64_t aStart, int64_t aEnd,
- const nsAString& aContentType, uint8_t aArgc,
- DOMFileImpl** aBlobImpl)
+already_AddRefed<DOMFileImpl>
+DOMFileImpl::Slice(const Optional<int64_t>& aStart,
+ const Optional<int64_t>& aEnd,
+ const nsAString& aContentType,
+ ErrorResult& aRv)
{
- *aBlobImpl = nullptr;
-
// Truncate aStart and aEnd so that we stay within this file.
- uint64_t thisLength;
- nsresult rv = GetSize(&thisLength);
- NS_ENSURE_SUCCESS(rv, rv);
-
- if (aArgc < 2) {
- aEnd = (int64_t)thisLength;
+ uint64_t thisLength = GetSize(aRv);
+ if (NS_WARN_IF(aRv.Failed())) {
+ return nullptr;
}
- ParseSize((int64_t)thisLength, aStart, aEnd);
-
- nsRefPtr<DOMFileImpl> impl =
- CreateSlice((uint64_t)aStart, (uint64_t)(aEnd - aStart), aContentType);
+ int64_t start = aStart.WasPassed() ? aStart.Value() : 0;
+ int64_t end = aEnd.WasPassed() ? aEnd.Value() : (int64_t)thisLength;
- if (!impl) {
- return NS_ERROR_UNEXPECTED;
- }
+ ParseSize((int64_t)thisLength, start, end);
- impl.forget(aBlobImpl);
- return NS_OK;
+ return CreateSlice((uint64_t)start, (uint64_t)(end - start),
+ aContentType, aRv);
}
////////////////////////////////////////////////////////////////////////////
// DOMFileImpl implementation
NS_IMPL_ISUPPORTS(DOMFileImpl, PIDOMFileImpl)
////////////////////////////////////////////////////////////////////////////
// DOMFileImplFile implementation
NS_IMPL_ISUPPORTS_INHERITED0(DOMFileImplFile, DOMFileImpl)
-nsresult
+void
DOMFileImplBase::GetName(nsAString& aName)
{
NS_ASSERTION(mIsFile, "Should only be called on files");
aName = mName;
- return NS_OK;
}
nsresult
DOMFileImplBase::GetPath(nsAString& aPath)
{
NS_ASSERTION(mIsFile, "Should only be called on files");
aPath = mPath;
return NS_OK;
}
-nsresult
-DOMFileImplBase::GetLastModifiedDate(JSContext* aCx,
- JS::MutableHandle<JS::Value> aDate)
-{
- JS::Rooted<JSObject*> date(aCx, JS_NewDateObjectMsec(aCx, JS_Now() / PR_USEC_PER_MSEC));
- if (!date) {
- return NS_ERROR_OUT_OF_MEMORY;
- }
-
- aDate.setObject(*date);
- return NS_OK;
-}
-
-nsresult
-DOMFileImplBase::GetMozFullPath(nsAString &aFileName)
+void
+DOMFileImplBase::GetMozFullPath(nsAString& aFileName, ErrorResult& aRv)
{
NS_ASSERTION(mIsFile, "Should only be called on files");
- // It is unsafe to call IsCallerChrome on a non-main thread. If
- // you hit the following assertion you need to figure out some other way to
- // determine privileges and call GetMozFullPathInternal.
- NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
+ aFileName.Truncate();
+
+ if (NS_IsMainThread()) {
+ if (nsContentUtils::IsCallerChrome()) {
+ GetMozFullPathInternal(aFileName, aRv);
+ }
- if (nsContentUtils::IsCallerChrome()) {
- return GetMozFullPathInternal(aFileName);
+ return;
}
- aFileName.Truncate();
- return NS_OK;
+
+ workers::WorkerPrivate* workerPrivate =
+ workers::GetCurrentThreadWorkerPrivate();
+ MOZ_ASSERT(workerPrivate);
+
+ if (workerPrivate->UsesSystemPrincipal()) {
+ GetMozFullPathInternal(aFileName, aRv);
+ }
}
-nsresult
-DOMFileImplBase::GetMozFullPathInternal(nsAString& aFileName)
+void
+DOMFileImplBase::GetMozFullPathInternal(nsAString& aFileName, ErrorResult& aRv)
{
if (!mIsFile) {
- return NS_ERROR_FAILURE;
+ aRv.Throw(NS_ERROR_FAILURE);
+ return;
}
aFileName.Truncate();
- return NS_OK;
}
-nsresult
-DOMFileImplBase::GetSize(uint64_t* aSize)
-{
- *aSize = mLength;
- return NS_OK;
-}
-
-nsresult
+void
DOMFileImplBase::GetType(nsAString& aType)
{
aType = mContentType;
- return NS_OK;
}
-nsresult
-DOMFileImplBase::GetMozLastModifiedDate(uint64_t* aLastModifiedDate)
+int64_t
+DOMFileImplBase::GetLastModified(ErrorResult& aRv)
{
NS_ASSERTION(mIsFile, "Should only be called on files");
if (IsDateUnknown()) {
mLastModificationDate = PR_Now();
}
- *aLastModifiedDate = mLastModificationDate;
- return NS_OK;
-}
-already_AddRefed<DOMFileImpl>
-DOMFileImplBase::CreateSlice(uint64_t aStart, uint64_t aLength,
- const nsAString& aContentType)
-{
- return nullptr;
-}
-
-nsresult
-DOMFileImplBase::GetInternalStream(nsIInputStream** aStream)
-{
- return NS_ERROR_NOT_IMPLEMENTED;
+ return mLastModificationDate / PR_USEC_PER_MSEC;
}
int64_t
DOMFileImplBase::GetFileId()
{
int64_t id = -1;
if (IsStoredFile() && IsWholeFile() && !IsSnapshot()) {
@@ -683,28 +877,32 @@ DOMFileImplBase::GetFileInfo(indexedDB::
}
nsresult
DOMFileImplBase::GetSendInfo(nsIInputStream** aBody,
uint64_t* aContentLength,
nsACString& aContentType,
nsACString& aCharset)
{
+ MOZ_ASSERT(aContentLength);
+
nsresult rv;
nsCOMPtr<nsIInputStream> stream;
- rv = this->GetInternalStream(getter_AddRefs(stream));
+ rv = GetInternalStream(getter_AddRefs(stream));
NS_ENSURE_SUCCESS(rv, rv);
- rv = this->GetSize(aContentLength);
- NS_ENSURE_SUCCESS(rv, rv);
+ ErrorResult error;
+ *aContentLength = GetSize(error);
+ if (NS_WARN_IF(error.Failed())) {
+ return error.ErrorCode();
+ }
- nsString contentType;
- rv = this->GetType(contentType);
- NS_ENSURE_SUCCESS(rv, rv);
+ nsAutoString contentType;
+ GetType(contentType);
CopyUTF16toUTF8(contentType, aContentType);
aCharset.Truncate();
stream.forget(aBody);
return NS_OK;
}
@@ -720,135 +918,115 @@ nsresult
DOMFileImplBase::SetMutable(bool aMutable)
{
nsresult rv = NS_OK;
NS_ENSURE_ARG(!mImmutable || !aMutable);
if (!mImmutable && !aMutable) {
// Force the content type and size to be cached
- nsString dummyString;
- rv = this->GetType(dummyString);
- NS_ENSURE_SUCCESS(rv, rv);
+ nsAutoString dummyString;
+ GetType(dummyString);
- uint64_t dummyInt;
- rv = this->GetSize(&dummyInt);
- NS_ENSURE_SUCCESS(rv, rv);
+ ErrorResult error;
+ GetSize(error);
+ if (NS_WARN_IF(error.Failed())) {
+ return error.ErrorCode();
+ }
}
mImmutable = !aMutable;
return rv;
}
////////////////////////////////////////////////////////////////////////////
// DOMFileImplFile implementation
already_AddRefed<DOMFileImpl>
DOMFileImplFile::CreateSlice(uint64_t aStart, uint64_t aLength,
- const nsAString& aContentType)
+ const nsAString& aContentType,
+ ErrorResult& aRv)
{
nsRefPtr<DOMFileImpl> impl =
new DOMFileImplFile(this, aStart, aLength, aContentType);
return impl.forget();
}
-nsresult
-DOMFileImplFile::GetMozFullPathInternal(nsAString& aFilename)
-{
- NS_ASSERTION(mIsFile, "Should only be called on files");
- return mFile->GetPath(aFilename);
-}
-
-nsresult
-DOMFileImplFile::GetLastModifiedDate(JSContext* aCx,
- JS::MutableHandle<JS::Value> aLastModifiedDate)
+void
+DOMFileImplFile::GetMozFullPathInternal(nsAString& aFilename, ErrorResult& aRv)
{
NS_ASSERTION(mIsFile, "Should only be called on files");
-
- PRTime msecs;
- if (IsDateUnknown()) {
- nsresult rv = mFile->GetLastModifiedTime(&msecs);
- NS_ENSURE_SUCCESS(rv, rv);
- mLastModificationDate = msecs;
- } else {
- msecs = mLastModificationDate;
- }
-
- JSObject* date = JS_NewDateObjectMsec(aCx, msecs);
- if (date) {
- aLastModifiedDate.setObject(*date);
- }
- else {
- date = JS_NewDateObjectMsec(aCx, JS_Now() / PR_USEC_PER_MSEC);
- aLastModifiedDate.setObject(*date);
- }
-
- return NS_OK;
+ aRv = mFile->GetPath(aFilename);
}
-nsresult
-DOMFileImplFile::GetSize(uint64_t* aFileSize)
+uint64_t
+DOMFileImplFile::GetSize(ErrorResult& aRv)
{
if (IsSizeUnknown()) {
NS_ASSERTION(mWholeFile,
"Should only use lazy size when using the whole file");
int64_t fileSize;
- nsresult rv = mFile->GetFileSize(&fileSize);
- NS_ENSURE_SUCCESS(rv, rv);
+ aRv = mFile->GetFileSize(&fileSize);
+ if (NS_WARN_IF(aRv.Failed())) {
+ return 0;
+ }
if (fileSize < 0) {
- return NS_ERROR_FAILURE;
+ aRv.Throw(NS_ERROR_FAILURE);
+ return 0;
}
mLength = fileSize;
}
- *aFileSize = mLength;
-
- return NS_OK;
+ return mLength;
}
-nsresult
+void
DOMFileImplFile::GetType(nsAString& aType)
{
if (mContentType.IsVoid()) {
NS_ASSERTION(mWholeFile,
"Should only use lazy ContentType when using the whole file");
nsresult rv;
nsCOMPtr<nsIMIMEService> mimeService =
do_GetService(NS_MIMESERVICE_CONTRACTID, &rv);
- NS_ENSURE_SUCCESS(rv, rv);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ aType.Truncate();
+ return;
+ }
nsAutoCString mimeType;
rv = mimeService->GetTypeFromFile(mFile, mimeType);
if (NS_FAILED(rv)) {
mimeType.Truncate();
}
AppendUTF8toUTF16(mimeType, mContentType);
mContentType.SetIsVoid(false);
}
aType = mContentType;
-
- return NS_OK;
}
-nsresult
-DOMFileImplFile::GetMozLastModifiedDate(uint64_t* aLastModifiedDate)
+int64_t
+DOMFileImplFile::GetLastModified(ErrorResult& aRv)
{
NS_ASSERTION(mIsFile, "Should only be called on files");
if (IsDateUnknown()) {
PRTime msecs;
- nsresult rv = mFile->GetLastModifiedTime(&msecs);
- NS_ENSURE_SUCCESS(rv, rv);
+ aRv = mFile->GetLastModifiedTime(&msecs);
+ if (NS_WARN_IF(aRv.Failed())) {
+ return 0;
+ }
+
mLastModificationDate = msecs;
}
- *aLastModifiedDate = mLastModificationDate;
- return NS_OK;
+
+ return mLastModificationDate;
}
const uint32_t sFileStreamFlags =
nsIFileInputStream::CLOSE_ON_EOF |
nsIFileInputStream::REOPEN_ON_REWIND |
nsIFileInputStream::DEFER_OPEN |
nsIFileInputStream::SHARE_DELETE;
@@ -872,17 +1050,18 @@ DOMFileImplFile::SetPath(const nsAString
////////////////////////////////////////////////////////////////////////////
// DOMFileImplMemory implementation
NS_IMPL_ISUPPORTS_INHERITED0(DOMFileImplMemory, DOMFileImpl)
already_AddRefed<DOMFileImpl>
DOMFileImplMemory::CreateSlice(uint64_t aStart, uint64_t aLength,
- const nsAString& aContentType)
+ const nsAString& aContentType,
+ ErrorResult& aRv)
{
nsRefPtr<DOMFileImpl> impl =
new DOMFileImplMemory(this, aStart, aLength, aContentType);
return impl.forget();
}
nsresult
DOMFileImplMemory::GetInternalStream(nsIInputStream** aStream)
@@ -997,43 +1176,43 @@ DOMFileImplMemory::DataOwner::EnsureMemo
////////////////////////////////////////////////////////////////////////////
// DOMFileImplTemporaryFileBlob implementation
NS_IMPL_ISUPPORTS_INHERITED0(DOMFileImplTemporaryFileBlob, DOMFileImpl)
already_AddRefed<DOMFileImpl>
DOMFileImplTemporaryFileBlob::CreateSlice(uint64_t aStart, uint64_t aLength,
- const nsAString& aContentType)
+ const nsAString& aContentType,
+ ErrorResult& aRv)
{
- if (aStart + aLength > mLength)
+ if (aStart + aLength > mLength) {
+ aRv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
+ }
nsRefPtr<DOMFileImpl> impl =
- new DOMFileImplTemporaryFileBlob(this, aStart + mStartPos, aLength,
- aContentType);
+ new DOMFileImplTemporaryFileBlob(this, aStart + mStartPos,
+ aLength, aContentType);
return impl.forget();
}
nsresult
DOMFileImplTemporaryFileBlob::GetInternalStream(nsIInputStream** aStream)
{
nsCOMPtr<nsIInputStream> stream =
new nsTemporaryFileInputStream(mFileDescOwner, mStartPos, mStartPos + mLength);
stream.forget(aStream);
return NS_OK;
}
-} // dom namespace
-} // mozilla namespace
-
////////////////////////////////////////////////////////////////////////////
// nsDOMFileList implementation
-NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(nsDOMFileList)
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(nsDOMFileList, mFiles)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsDOMFileList)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMFileList)
NS_INTERFACE_MAP_ENTRY(nsIDOMFileList)
NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsDOMFileList)
@@ -1051,12 +1230,15 @@ nsDOMFileList::GetLength(uint32_t* aLeng
*aLength = Length();
return NS_OK;
}
NS_IMETHODIMP
nsDOMFileList::Item(uint32_t aIndex, nsIDOMFile **aFile)
{
- NS_IF_ADDREF(*aFile = Item(aIndex));
-
+ nsRefPtr<DOMFile> file = Item(aIndex);
+ file.forget(aFile);
return NS_OK;
}
+
+} // dom namespace
+} // mozilla namespace
--- a/content/base/src/nsDOMFileReader.cpp
+++ b/content/base/src/nsDOMFileReader.cpp
@@ -181,45 +181,49 @@ nsDOMFileReader::GetError(nsISupports**
return NS_OK;
}
NS_IMETHODIMP
nsDOMFileReader::ReadAsArrayBuffer(nsIDOMBlob* aFile, JSContext* aCx)
{
NS_ENSURE_TRUE(aFile, NS_ERROR_NULL_POINTER);
ErrorResult rv;
- ReadAsArrayBuffer(aCx, aFile, rv);
+ nsRefPtr<DOMFile> file = static_cast<DOMFile*>(aFile);
+ ReadAsArrayBuffer(aCx, *file, rv);
return rv.ErrorCode();
}
NS_IMETHODIMP
nsDOMFileReader::ReadAsBinaryString(nsIDOMBlob* aFile)
{
NS_ENSURE_TRUE(aFile, NS_ERROR_NULL_POINTER);
ErrorResult rv;
- ReadAsBinaryString(aFile, rv);
+ nsRefPtr<DOMFile> file = static_cast<DOMFile*>(aFile);
+ ReadAsBinaryString(*file, rv);
return rv.ErrorCode();
}
NS_IMETHODIMP
nsDOMFileReader::ReadAsText(nsIDOMBlob* aFile,
const nsAString &aCharset)
{
NS_ENSURE_TRUE(aFile, NS_ERROR_NULL_POINTER);
ErrorResult rv;
- ReadAsText(aFile, aCharset, rv);
+ nsRefPtr<DOMFile> file = static_cast<DOMFile*>(aFile);
+ ReadAsText(*file, aCharset, rv);
return rv.ErrorCode();
}
NS_IMETHODIMP
nsDOMFileReader::ReadAsDataURL(nsIDOMBlob* aFile)
{
NS_ENSURE_TRUE(aFile, NS_ERROR_NULL_POINTER);
ErrorResult rv;
- ReadAsDataURL(aFile, rv);
+ nsRefPtr<DOMFile> file = static_cast<DOMFile*>(aFile);
+ ReadAsDataURL(*file, rv);
return rv.ErrorCode();
}
NS_IMETHODIMP
nsDOMFileReader::Abort()
{
ErrorResult rv;
FileIOObject::Abort(rv);
@@ -361,33 +365,31 @@ nsDOMFileReader::DoReadData(nsIAsyncInpu
mDataLen += aCount;
return NS_OK;
}
// Helper methods
void
nsDOMFileReader::ReadFileContent(JSContext* aCx,
- nsIDOMBlob* aFile,
+ DOMFile& aFile,
const nsAString &aCharset,
eDataFormat aDataFormat,
ErrorResult& aRv)
{
- MOZ_ASSERT(aFile);
-
//Implicit abort to clear any other activity going on
Abort();
mError = nullptr;
SetDOMStringToNull(mResult);
mTransferred = 0;
mTotal = 0;
mReadyState = nsIDOMFileReader::EMPTY;
FreeFileData();
- mFile = aFile;
+ mFile = &aFile;
mDataFormat = aDataFormat;
CopyUTF16toUTF8(aCharset, mCharset);
nsresult rv;
nsCOMPtr<nsIStreamTransportService> sts =
do_GetService(kStreamTransportServiceCID, &rv);
if (NS_WARN_IF(NS_FAILED(rv))) {
--- a/content/base/src/nsDOMFileReader.h
+++ b/content/base/src/nsDOMFileReader.h
@@ -14,30 +14,36 @@
#include "nsIInterfaceRequestor.h"
#include "nsJSUtils.h"
#include "nsTArray.h"
#include "nsIJSNativeInitializer.h"
#include "prtime.h"
#include "nsITimer.h"
#include "nsIAsyncInputStream.h"
-#include "nsIDOMFile.h"
#include "nsIDOMFileReader.h"
#include "nsIDOMFileList.h"
#include "nsCOMPtr.h"
#include "FileIOObject.h"
+namespace mozilla {
+namespace dom {
+class DOMFile;
+}
+}
+
class nsDOMFileReader : public mozilla::dom::FileIOObject,
public nsIDOMFileReader,
public nsIInterfaceRequestor,
public nsSupportsWeakReference
{
typedef mozilla::ErrorResult ErrorResult;
typedef mozilla::dom::GlobalObject GlobalObject;
+ typedef mozilla::dom::DOMFile DOMFile;
public:
nsDOMFileReader();
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIDOMFILEREADER
NS_REALLY_FORWARD_NSIDOMEVENTTARGET(mozilla::DOMEventTargetHelper)
@@ -57,31 +63,28 @@ public:
{
return GetOwner();
}
virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
// WebIDL
static already_AddRefed<nsDOMFileReader>
Constructor(const GlobalObject& aGlobal, ErrorResult& aRv);
- void ReadAsArrayBuffer(JSContext* aCx, nsIDOMBlob* aBlob, ErrorResult& aRv)
+ void ReadAsArrayBuffer(JSContext* aCx, DOMFile& aBlob, ErrorResult& aRv)
{
- MOZ_ASSERT(aBlob);
ReadFileContent(aCx, aBlob, EmptyString(), FILE_AS_ARRAYBUFFER, aRv);
}
- void ReadAsText(nsIDOMBlob* aBlob, const nsAString& aLabel, ErrorResult& aRv)
+ void ReadAsText(DOMFile& aBlob, const nsAString& aLabel, ErrorResult& aRv)
{
- MOZ_ASSERT(aBlob);
ReadFileContent(nullptr, aBlob, aLabel, FILE_AS_TEXT, aRv);
}
- void ReadAsDataURL(nsIDOMBlob* aBlob, ErrorResult& aRv)
+ void ReadAsDataURL(DOMFile& aBlob, ErrorResult& aRv)
{
- MOZ_ASSERT(aBlob);
ReadFileContent(nullptr, aBlob, EmptyString(), FILE_AS_DATAURL, aRv);
}
using FileIOObject::Abort;
// Inherited ReadyState().
void GetResult(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
@@ -94,19 +97,18 @@ public:
using FileIOObject::SetOnprogress;
IMPL_EVENT_HANDLER(load)
using FileIOObject::GetOnabort;
using FileIOObject::SetOnabort;
using FileIOObject::GetOnerror;
using FileIOObject::SetOnerror;
IMPL_EVENT_HANDLER(loadend)
- void ReadAsBinaryString(nsIDOMBlob* aBlob, ErrorResult& aRv)
+ void ReadAsBinaryString(DOMFile& aBlob, ErrorResult& aRv)
{
- MOZ_ASSERT(aBlob);
ReadFileContent(nullptr, aBlob, EmptyString(), FILE_AS_BINARY, aRv);
}
nsresult Init();
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(nsDOMFileReader,
FileIOObject)
@@ -117,17 +119,17 @@ protected:
enum eDataFormat {
FILE_AS_ARRAYBUFFER,
FILE_AS_BINARY,
FILE_AS_TEXT,
FILE_AS_DATAURL
};
- void ReadFileContent(JSContext* aCx, nsIDOMBlob* aBlob,
+ void ReadFileContent(JSContext* aCx, DOMFile& aBlob,
const nsAString &aCharset, eDataFormat aDataFormat,
ErrorResult& aRv);
nsresult GetAsText(nsIDOMBlob *aFile, const nsACString &aCharset,
const char *aFileData, uint32_t aDataLen, nsAString &aResult);
nsresult GetAsDataURL(nsIDOMBlob *aFile, const char *aFileData, uint32_t aDataLen, nsAString &aResult);
void FreeFileData() {
moz_free(mFileData);
--- a/content/base/src/nsFormData.cpp
+++ b/content/base/src/nsFormData.cpp
@@ -1,34 +1,59 @@
/* 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 "nsDOMFile.h"
#include "nsFormData.h"
#include "nsIVariant.h"
#include "nsIInputStream.h"
-#include "nsIDOMFile.h"
#include "mozilla/dom/HTMLFormElement.h"
#include "mozilla/dom/FormDataBinding.h"
using namespace mozilla;
using namespace mozilla::dom;
nsFormData::nsFormData(nsISupports* aOwner)
: nsFormSubmission(NS_LITERAL_CSTRING("UTF-8"), nullptr)
, mOwner(aOwner)
{
}
// -------------------------------------------------------------------------
// nsISupports
-NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(nsFormData, mOwner)
+NS_IMPL_CYCLE_COLLECTION_CLASS(nsFormData)
+
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsFormData)
+ NS_IMPL_CYCLE_COLLECTION_UNLINK(mOwner)
+
+ for (uint32_t i = 0, len = tmp->mFormData.Length(); i < len; ++i) {
+ ImplCycleCollectionUnlink(tmp->mFormData[i].fileValue);
+ }
+
+ NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsFormData)
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOwner)
+
+ for (uint32_t i = 0, len = tmp->mFormData.Length(); i < len; ++i) {
+ ImplCycleCollectionTraverse(cb,tmp->mFormData[i].fileValue,
+ "mFormData[i].fileValue", 0);
+ }
+
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+
+NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(nsFormData)
+
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsFormData)
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsFormData)
+
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsFormData)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsIDOMFormData)
NS_INTERFACE_MAP_ENTRY(nsIXHRSendable)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMFormData)
NS_INTERFACE_MAP_END
// -------------------------------------------------------------------------
@@ -43,26 +68,26 @@ nsFormData::GetEncodedSubmission(nsIURI*
void
nsFormData::Append(const nsAString& aName, const nsAString& aValue)
{
AddNameValuePair(aName, aValue);
}
void
-nsFormData::Append(const nsAString& aName, nsIDOMBlob* aBlob,
+nsFormData::Append(const nsAString& aName, DOMFile& aBlob,
const Optional<nsAString>& aFilename)
{
nsString filename;
if (aFilename.WasPassed()) {
filename = aFilename.Value();
} else {
filename.SetIsVoid(true);
}
- AddNameFilePair(aName, aBlob, filename);
+ AddNameFilePair(aName, &aBlob, filename);
}
// -------------------------------------------------------------------------
// nsIDOMFormData
NS_IMETHODIMP
nsFormData::Append(const nsAString& aName, nsIVariant* aValue)
{
@@ -75,19 +100,20 @@ nsFormData::Append(const nsAString& aNam
nsCOMPtr<nsISupports> supports;
nsID *iid;
rv = aValue->GetAsInterface(&iid, getter_AddRefs(supports));
NS_ENSURE_SUCCESS(rv, rv);
nsMemory::Free(iid);
nsCOMPtr<nsIDOMBlob> domBlob = do_QueryInterface(supports);
+ nsRefPtr<DOMFile> blob = static_cast<DOMFile*>(domBlob.get());
if (domBlob) {
Optional<nsAString> temp;
- Append(aName, domBlob, temp);
+ Append(aName, *blob, temp);
return NS_OK;
}
}
char16_t* stringData = nullptr;
uint32_t stringLen = 0;
rv = aValue->GetAsWStringWithSize(&stringLen, &stringData);
NS_ENSURE_SUCCESS(rv, rv);
--- a/content/base/src/nsFormData.h
+++ b/content/base/src/nsFormData.h
@@ -1,31 +1,29 @@
/* 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/. */
#ifndef nsFormData_h__
#define nsFormData_h__
#include "mozilla/Attributes.h"
-#include "nsIDOMFile.h"
#include "nsIDOMFormData.h"
#include "nsIXMLHttpRequest.h"
#include "nsFormSubmission.h"
#include "nsWrapperCache.h"
#include "nsTArray.h"
#include "mozilla/ErrorResult.h"
#include "mozilla/dom/BindingDeclarations.h"
-class nsIDOMFile;
-
namespace mozilla {
class ErrorResult;
namespace dom {
+class DOMFile;
class HTMLFormElement;
class GlobalObject;
} // namespace dom
} // namespace mozilla
class nsFormData MOZ_FINAL : public nsIDOMFormData,
public nsIXHRSendable,
public nsFormSubmission,
@@ -52,17 +50,17 @@ public:
{
return mOwner;
}
static already_AddRefed<nsFormData>
Constructor(const mozilla::dom::GlobalObject& aGlobal,
const mozilla::dom::Optional<mozilla::dom::NonNull<mozilla::dom::HTMLFormElement> >& aFormElement,
mozilla::ErrorResult& aRv);
void Append(const nsAString& aName, const nsAString& aValue);
- void Append(const nsAString& aName, nsIDOMBlob* aBlob,
+ void Append(const nsAString& aName, mozilla::dom::DOMFile& aBlob,
const mozilla::dom::Optional<nsAString>& aFilename);
// nsFormSubmission
virtual nsresult GetEncodedSubmission(nsIURI* aURI,
nsIInputStream** aPostDataStream) MOZ_OVERRIDE;
virtual nsresult AddNameValuePair(const nsAString& aName,
const nsAString& aValue) MOZ_OVERRIDE
{
--- a/content/base/src/nsFrameMessageManager.cpp
+++ b/content/base/src/nsFrameMessageManager.cpp
@@ -199,17 +199,17 @@ template<ActorFlavorEnum Flavor>
static bool
BuildClonedMessageData(typename BlobTraits<Flavor>::ConcreteContentManagerType* aManager,
const StructuredCloneData& aData,
ClonedMessageData& aClonedData)
{
SerializedStructuredCloneBuffer& buffer = aClonedData.data();
buffer.data = aData.mData;
buffer.dataLength = aData.mDataLength;
- const nsTArray<nsCOMPtr<nsIDOMBlob> >& blobs = aData.mClosure.mBlobs;
+ const nsTArray<nsRefPtr<DOMFile>>& blobs = aData.mClosure.mBlobs;
if (!blobs.IsEmpty()) {
typedef typename BlobTraits<Flavor>::ProtocolType ProtocolType;
InfallibleTArray<ProtocolType*>& blobList = DataBlobs<Flavor>::Blobs(aClonedData);
uint32_t length = blobs.Length();
blobList.SetCapacity(length);
for (uint32_t i = 0; i < length; ++i) {
typename BlobTraits<Flavor>::BlobType* protocolActor =
aManager->GetOrCreateActorForBlob(blobs[i]);
@@ -250,18 +250,23 @@ UnpackClonedMessageData(const ClonedMess
cloneData.mDataLength = buffer.dataLength;
if (!blobs.IsEmpty()) {
uint32_t length = blobs.Length();
cloneData.mClosure.mBlobs.SetCapacity(length);
for (uint32_t i = 0; i < length; ++i) {
auto* blob =
static_cast<typename BlobTraits<Flavor>::BlobType*>(blobs[i]);
MOZ_ASSERT(blob);
- nsCOMPtr<nsIDOMBlob> domBlob = blob->GetBlob();
- MOZ_ASSERT(domBlob);
+
+ nsRefPtr<DOMFileImpl> blobImpl = blob->GetBlobImpl();
+ MOZ_ASSERT(blobImpl);
+
+ // This object will be duplicated with a correct parent before being
+ // exposed to JS.
+ nsRefPtr<DOMFile> domBlob = new DOMFile(nullptr, blobImpl);
cloneData.mClosure.mBlobs.AppendElement(domBlob);
}
}
return cloneData;
}
StructuredCloneData
mozilla::dom::ipc::UnpackClonedMessageDataForParent(const ClonedMessageData& aData)
--- a/content/base/src/nsHostObjectProtocolHandler.cpp
+++ b/content/base/src/nsHostObjectProtocolHandler.cpp
@@ -13,16 +13,17 @@
#include "nsDOMFile.h"
#include "DOMMediaStream.h"
#include "mozilla/dom/MediaSource.h"
#include "nsIMemoryReporter.h"
#include "mozilla/Preferences.h"
#include "mozilla/LoadInfo.h"
using mozilla::dom::DOMFileImpl;
+using mozilla::ErrorResult;
using mozilla::LoadInfo;
// -----------------------------------------------------------------------
// Hash table
struct DataInfo
{
// mObject is expected to be an nsIDOMBlob, DOMMediaStream, or MediaSource
nsCOMPtr<nsISupports> mObject;
@@ -517,29 +518,29 @@ nsHostObjectProtocolHandler::NewChannel(
nsCOMPtr<nsIChannel> channel;
rv = NS_NewInputStreamChannel(getter_AddRefs(channel),
uri,
stream);
NS_ENSURE_SUCCESS(rv, rv);
nsString type;
- rv = blob->GetType(type);
- NS_ENSURE_SUCCESS(rv, rv);
+ blob->GetType(type);
if (blob->IsFile()) {
nsString filename;
- rv = blob->GetName(filename);
- NS_ENSURE_SUCCESS(rv, rv);
+ blob->GetName(filename);
channel->SetContentDispositionFilename(filename);
}
- uint64_t size;
- rv = blob->GetSize(&size);
- NS_ENSURE_SUCCESS(rv, rv);
+ ErrorResult error;
+ uint64_t size = blob->GetSize(error);
+ if (NS_WARN_IF(error.Failed())) {
+ return error.ErrorCode();
+ }
nsCOMPtr<nsILoadInfo> loadInfo =
new mozilla::LoadInfo(info->mPrincipal,
nullptr,
nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL,
nsIContentPolicy::TYPE_OTHER);
channel->SetLoadInfo(loadInfo);
channel->SetOriginalURI(uri);
--- a/content/base/src/nsXMLHttpRequest.cpp
+++ b/content/base/src/nsXMLHttpRequest.cpp
@@ -779,33 +779,34 @@ nsXMLHttpRequest::CreatePartialBlob()
{
if (mDOMFile) {
// Use progress info to determine whether load is complete, but use
// mDataAvailable to ensure a slice is created based on the uncompressed
// data count.
if (mLoadTotal == mLoadTransferred) {
mResponseBlob = mDOMFile;
} else {
- mResponseBlob =
- mDOMFile->CreateSlice(0, mDataAvailable, EmptyString());
+ ErrorResult rv;
+ mResponseBlob = mDOMFile->CreateSlice(0, mDataAvailable,
+ EmptyString(), rv);
}
return;
}
// mBlobSet can be null if the request has been canceled
if (!mBlobSet) {
return;
}
nsAutoCString contentType;
if (mLoadTotal == mLoadTransferred) {
mChannel->GetContentType(contentType);
}
- mResponseBlob = mBlobSet->GetBlobInternal(contentType);
+ mResponseBlob = mBlobSet->GetBlobInternal(GetOwner(), contentType);
}
/* attribute AString responseType; */
NS_IMETHODIMP nsXMLHttpRequest::GetResponseType(nsAString& aResponseType)
{
switch (mResponseType) {
case XML_HTTP_RESPONSE_TYPE_DEFAULT:
aResponseType.Truncate();
@@ -1002,17 +1003,17 @@ nsXMLHttpRequest::GetResponse(JSContext*
}
}
if (!mResponseBlob) {
aResponse.setNull();
return;
}
- aRv = nsContentUtils::WrapNative(aCx, mResponseBlob, aResponse);
+ WrapNewBindingObject(aCx, mResponseBlob, aResponse);
return;
}
case XML_HTTP_RESPONSE_TYPE_DOCUMENT:
{
if (!(mState & XML_HTTP_REQUEST_DONE) || !mResponseXML) {
aResponse.setNull();
return;
}
@@ -1893,17 +1894,17 @@ bool nsXMLHttpRequest::CreateDOMFile(nsI
if (!file)
return false;
nsAutoCString contentType;
mChannel->GetContentType(contentType);
mDOMFile =
- DOMFile::CreateFromFile(file, EmptyString(),
+ DOMFile::CreateFromFile(GetOwner(), file, EmptyString(),
NS_ConvertASCIItoUTF16(contentType));
mBlobSet = nullptr;
NS_ASSERTION(mResponseBody.IsEmpty(), "mResponseBody should be empty");
return true;
}
NS_IMETHODIMP
@@ -2238,17 +2239,17 @@ nsXMLHttpRequest::OnStopRequest(nsIReque
// and if the response length is zero.
if (!mBlobSet) {
mBlobSet = new BlobSet();
}
// Smaller files may be written in cache map instead of separate files.
// Also, no-store response cannot be written in persistent cache.
nsAutoCString contentType;
mChannel->GetContentType(contentType);
- mResponseBlob = mBlobSet->GetBlobInternal(contentType);
+ mResponseBlob = mBlobSet->GetBlobInternal(GetOwner(), contentType);
mBlobSet = nullptr;
}
NS_ASSERTION(mResponseBody.IsEmpty(), "mResponseBody should be empty");
NS_ASSERTION(mResponseText.IsEmpty(), "mResponseText should be empty");
} else if (NS_SUCCEEDED(status) &&
((mResponseType == XML_HTTP_RESPONSE_TYPE_ARRAYBUFFER &&
!mIsMappedArrayBuffer) ||
mResponseType == XML_HTTP_RESPONSE_TYPE_CHUNKED_ARRAYBUFFER)) {
@@ -2613,17 +2614,18 @@ nsXMLHttpRequest::GetRequestBody(nsIVari
const ArrayBufferView* view = value.mArrayBufferView;
view->ComputeLengthAndData();
return ::GetRequestBody(view->Data(), view->Length(), aResult,
aContentLength, aContentType, aCharset);
}
case nsXMLHttpRequest::RequestBody::Blob:
{
nsresult rv;
- nsCOMPtr<nsIXHRSendable> sendable = do_QueryInterface(value.mBlob, &rv);
+ nsCOMPtr<nsIDOMBlob> blob = value.mBlob;
+ nsCOMPtr<nsIXHRSendable> sendable = do_QueryInterface(blob, &rv);
NS_ENSURE_SUCCESS(rv, rv);
return ::GetRequestBody(sendable, aResult, aContentLength, aContentType, aCharset);
}
case nsXMLHttpRequest::RequestBody::Document:
{
nsCOMPtr<nsIDOMDocument> document = do_QueryInterface(value.mDocument);
return ::GetRequestBody(document, aResult, aContentLength, aContentType, aCharset);
--- a/content/base/src/nsXMLHttpRequest.h
+++ b/content/base/src/nsXMLHttpRequest.h
@@ -345,19 +345,19 @@ private:
explicit RequestBody(const mozilla::dom::ArrayBuffer* aArrayBuffer) : mType(ArrayBuffer)
{
mValue.mArrayBuffer = aArrayBuffer;
}
explicit RequestBody(const mozilla::dom::ArrayBufferView* aArrayBufferView) : mType(ArrayBufferView)
{
mValue.mArrayBufferView = aArrayBufferView;
}
- explicit RequestBody(nsIDOMBlob* aBlob) : mType(Blob)
+ explicit RequestBody(mozilla::dom::DOMFile& aBlob) : mType(Blob)
{
- mValue.mBlob = aBlob;
+ mValue.mBlob = &aBlob;
}
explicit RequestBody(nsIDocument* aDocument) : mType(Document)
{
mValue.mDocument = aDocument;
}
explicit RequestBody(const nsAString& aString) : mType(DOMString)
{
mValue.mString = &aString;
@@ -379,17 +379,17 @@ private:
Document,
DOMString,
FormData,
InputStream
};
union Value {
const mozilla::dom::ArrayBuffer* mArrayBuffer;
const mozilla::dom::ArrayBufferView* mArrayBufferView;
- nsIDOMBlob* mBlob;
+ mozilla::dom::DOMFile* mBlob;
nsIDocument* mDocument;
const nsAString* mString;
nsFormData* mFormData;
nsIInputStream* mStream;
};
Type GetType() const
{
@@ -435,19 +435,18 @@ public:
{
aRv = Send(RequestBody(&aArrayBuffer));
}
void Send(const mozilla::dom::ArrayBufferView& aArrayBufferView,
ErrorResult& aRv)
{
aRv = Send(RequestBody(&aArrayBufferView));
}
- void Send(nsIDOMBlob* aBlob, ErrorResult& aRv)
+ void Send(mozilla::dom::DOMFile& aBlob, ErrorResult& aRv)
{
- NS_ASSERTION(aBlob, "Null should go to string version");
aRv = Send(RequestBody(aBlob));
}
void Send(nsIDocument& aDoc, ErrorResult& aRv)
{
aRv = Send(RequestBody(&aDoc));
}
void Send(const nsAString& aString, ErrorResult& aRv)
{
@@ -667,17 +666,17 @@ protected:
};
void SetResponseType(nsXMLHttpRequest::ResponseTypeEnum aType, ErrorResult& aRv);
ResponseTypeEnum mResponseType;
// It is either a cached blob-response from the last call to GetResponse,
// but is also explicitly set in OnStopRequest.
- nsCOMPtr<nsIDOMBlob> mResponseBlob;
+ nsRefPtr<mozilla::dom::DOMFile> mResponseBlob;
// Non-null only when we are able to get a os-file representation of the
// response, i.e. when loading from a file.
nsRefPtr<mozilla::dom::DOMFile> mDOMFile;
// We stream data to mBlobSet when response type is "blob" or "moz-blob"
// and mDOMFile is null.
nsAutoPtr<BlobSet> mBlobSet;
nsString mOverrideMimeType;
--- a/content/base/test/chrome/test_bug914381.html
+++ b/content/base/test/chrome/test_bug914381.html
@@ -30,19 +30,19 @@ function createFileWithData(fileData) {
outStream.write(fileData, fileData.length);
outStream.close();
return testFile;
}
/** Test for Bug 914381. DOMFile's created in JS using an nsIFile should allow mozGetFullPathInternal calls to succeed **/
var file = createFileWithData("Test bug 914381");
-var f = File(file);
+var f = new File(file);
is(f.mozFullPathInternal, undefined, "mozFullPathInternal is undefined from js");
is(f.mozFullPath, file.path, "mozFullPath returns path if created with nsIFile");
-f = File(file.path);
+f = new File(file.path);
is(f.mozFullPathInternal, undefined, "mozFullPathInternal is undefined from js");
is(f.mozFullPath, "", "mozFullPath returns blank if created with a string");
</script>
</pre>
</body>
</html>
--- a/content/base/test/test_blobconstructor.html
+++ b/content/base/test/test_blobconstructor.html
@@ -15,75 +15,75 @@ https://bugzilla.mozilla.org/show_bug.cg
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script class="testbody" type="text/javascript;version=1.7">
"use strict";
/** Test for Bug 721569 **/
-var blob = Blob();
+var blob = new Blob();
ok(blob, "Blob should exist");
ok(blob.size !== undefined, "Blob should have a size property");
ok(blob.type !== undefined, "Blob should have a type property");
ok(blob.slice, "Blob should have a slice method");
-blob = Blob([], {type: null});
+blob = new Blob([], {type: null});
ok(blob, "Blob should exist");
is(blob.type, "null", "Blob type should be stringified");
-blob = Blob([], {type: undefined});
+blob = new Blob([], {type: undefined});
ok(blob, "Blob should exist");
is(blob.type, "", "Blob type should be treated as missing");
try {
-blob = Blob([]);
+blob = new Blob([]);
ok(true, "an empty blobParts argument should not throw");
} catch(e) {
ok(false, "NOT REACHED");
}
try {
-blob = Blob(null);
+blob = new Blob(null);
ok(false, "NOT REACHED");
} catch(e) {
ok(true, "a null blobParts member should throw");
}
try {
-blob = Blob([], null);
+blob = new Blob([], null);
ok(true, "a null options member should not throw");
} catch(e) {
ok(false, "NOT REACHED");
}
try {
-blob = Blob([], undefined);
+blob = new Blob([], undefined);
ok(true, "an undefined options member should not throw");
} catch(e) {
ok(false, "NOT REACHED");
}
try {
-blob = Blob([], false);
+blob = new Blob([], false);
ok(false, "NOT REACHED");
} catch(e) {
ok(true, "a boolean options member should throw");
}
try {
-blob = Blob([], 0);
+blob = new Blob([], 0);
ok(false, "NOT REACHED");
} catch(e) {
ok(true, "a numeric options member should throw");
}
try {
-blob = Blob([], "");
+blob = new Blob([], "");
ok(false, "NOT REACHED");
} catch(e) {
ok(true, "a string options member should throw");
}
/** Test for dictionary initialization order **/
(function() {
var o = {};
@@ -95,23 +95,23 @@ ok(true, "a string options member should
}
["type", "endings"].forEach(function(n) {
Object.defineProperty(o, n, { get: add_to_called.bind(null, n) });
});
var b = new Blob([], o);
is(JSON.stringify(called), JSON.stringify(["endings", "type"]), "dictionary members should be get in lexicographical order");
})();
-let blob1 = Blob(["squiggle"]);
+let blob1 = new Blob(["squiggle"]);
ok(blob1 instanceof Blob, "Blob constructor should produce Blobs");
ok(!(blob1 instanceof File), "Blob constructor should not produce Files");
is(blob1.type, "", "Blob constructor with no options should return Blob with empty type");
is(blob1.size, 8, "Blob constructor should return Blob with correct size");
-let blob2 = Blob(["steak"], {type: "content/type"});
+let blob2 = new Blob(["steak"], {type: "content/type"});
ok(blob2 instanceof Blob, "Blob constructor should produce Blobs");
ok(!(blob2 instanceof File), "Blob constructor should not produce Files");
is(blob2.type, "content/type", "Blob constructor with a type option should return Blob with the type");
is(blob2.size, 5, "Blob constructor should return Blob with correct size");
let aB = new ArrayBuffer(16);
var int8View = new Int8Array(aB);
--- a/content/base/test/test_bug403852.html
+++ b/content/base/test/test_bug403852.html
@@ -8,17 +8,16 @@ https://bugzilla.mozilla.org/show_bug.cg
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=403852">Mozilla Bug 403852</a>
<p id="display">
<input id="fileList" type="file"></input>
- <canvas id="canvas"></canvas>
</p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
var testFile = SpecialPowers.Services.dirsvc.get("ProfD", SpecialPowers.Ci.nsIFile);
@@ -32,19 +31,23 @@ var domFile = fileList.files[0];
is(domFile.name, "prefs.js", "fileName should be prefs.js");
ok("lastModifiedDate" in domFile, "lastModifiedDate must be present");
var d = new Date(testFile.lastModifiedTime);
ok(d.getTime() == domFile.lastModifiedDate.getTime(), "lastModifiedDate should be the same.");
-var cf = document.getElementById("canvas").mozGetAsFile("canvFile");
+var x = new Date();
-var x = new Date();
-var y = cf.lastModifiedDate;
+// In our implementation of File object, lastModifiedDate is unknown only for new objects.
+// Using canvas or input[type=file] elements, we 'often' have a valid lastModifiedDate values.
+// For canvas we use memory files and the lastModifiedDate is now().
+var f = new File([new Blob(['test'], {type: 'text/plain'})], "test-name");
+
+var y = f.lastModifiedDate;
var z = new Date();
ok((x.getTime() <= y.getTime()) && (y.getTime() <= z.getTime()), "lastModifiedDate of file which does not have last modified date should be current time");
</script>
</pre>
</body> </html>
--- a/content/html/content/public/HTMLCanvasElement.h
+++ b/content/html/content/public/HTMLCanvasElement.h
@@ -11,31 +11,31 @@
#include "nsGenericHTMLElement.h"
#include "nsGkAtoms.h"
#include "nsSize.h"
#include "nsError.h"
#include "mozilla/gfx/Rect.h"
class nsICanvasRenderingContextInternal;
-class nsIDOMFile;
class nsITimerCallback;
namespace mozilla {
namespace layers {
class CanvasLayer;
class LayerManager;
}
namespace gfx {
class SourceSurface;
}
namespace dom {
+class DOMFile;
class FileCallback;
class HTMLCanvasPrintState;
class PrintCallback;
class HTMLCanvasElement MOZ_FINAL : public nsGenericHTMLElement,
public nsIDOMHTMLCanvasElement
{
enum {
@@ -97,19 +97,19 @@ public:
bool MozOpaque() const
{
return GetBoolAttr(nsGkAtoms::moz_opaque);
}
void SetMozOpaque(bool aValue, ErrorResult& aRv)
{
SetHTMLBoolAttr(nsGkAtoms::moz_opaque, aValue, aRv);
}
- already_AddRefed<nsIDOMFile> MozGetAsFile(const nsAString& aName,
- const nsAString& aType,
- ErrorResult& aRv);
+ already_AddRefed<DOMFile> MozGetAsFile(const nsAString& aName,
+ const nsAString& aType,
+ ErrorResult& aRv);
already_AddRefed<nsISupports> MozGetIPCContext(const nsAString& aContextId,
ErrorResult& aRv)
{
nsCOMPtr<nsISupports> context;
aRv = MozGetIPCContext(aContextId, getter_AddRefs(context));
return context.forget();
}
void MozFetchAsStream(nsIInputStreamCallback* aCallback,
--- a/content/html/content/src/HTMLCanvasElement.cpp
+++ b/content/html/content/src/HTMLCanvasElement.cpp
@@ -555,18 +555,20 @@ HTMLCanvasElement::ToBlob(JSContext* aCx
uint64_t size;
nsresult rv = blob->GetSize(&size);
if (NS_SUCCEEDED(rv)) {
AutoJSAPI jsapi;
jsapi.Init(mGlobal);
JS_updateMallocCounter(jsapi.cx(), size);
}
+ nsRefPtr<DOMFile> newBlob = new DOMFile(mGlobal, blob->Impl());
+
mozilla::ErrorResult error;
- mFileCallback->Call(blob, error);
+ mFileCallback->Call(*newBlob, error);
mGlobal = nullptr;
mFileCallback = nullptr;
return error.ErrorCode();
}
nsCOMPtr<nsIGlobalObject> mGlobal;
@@ -580,24 +582,25 @@ HTMLCanvasElement::ToBlob(JSContext* aCx
params,
usingCustomParseOptions,
imageBuffer,
format,
GetSize(),
callback);
}
-already_AddRefed<nsIDOMFile>
+already_AddRefed<DOMFile>
HTMLCanvasElement::MozGetAsFile(const nsAString& aName,
const nsAString& aType,
ErrorResult& aRv)
{
nsCOMPtr<nsIDOMFile> file;
aRv = MozGetAsFile(aName, aType, getter_AddRefs(file));
- return file.forget();
+ nsRefPtr<DOMFile> tmp = static_cast<DOMFile*>(file.get());
+ return tmp.forget();
}
NS_IMETHODIMP
HTMLCanvasElement::MozGetAsFile(const nsAString& aName,
const nsAString& aType,
nsIDOMFile** aResult)
{
OwnerDoc()->WarnOnceAbout(nsIDocument::eMozGetAsFile);
@@ -630,19 +633,21 @@ HTMLCanvasElement::MozGetAsFileImpl(cons
rv = NS_ReadInputStreamToBuffer(stream, &imgData, (uint32_t)imgSize);
NS_ENSURE_SUCCESS(rv, rv);
JSContext* cx = nsContentUtils::GetCurrentJSContext();
if (cx) {
JS_updateMallocCounter(cx, imgSize);
}
+ nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(OwnerDoc()->GetScopeObject());
+
// The DOMFile takes ownership of the buffer
nsRefPtr<DOMFile> file =
- DOMFile::CreateMemoryFile(imgData, (uint32_t)imgSize, aName, type,
+ DOMFile::CreateMemoryFile(win, imgData, (uint32_t)imgSize, aName, type,
PR_Now());
file.forget(aResult);
return NS_OK;
}
nsresult
HTMLCanvasElement::GetContextHelper(const nsAString& aContextId,
--- a/content/html/content/src/HTMLInputElement.cpp
+++ b/content/html/content/src/HTMLInputElement.cpp
@@ -231,36 +231,36 @@ class HTMLInputElementState MOZ_FINAL :
const nsString& GetValue() {
return mValue;
}
void SetValue(const nsAString& aValue) {
mValue = aValue;
}
- const nsTArray<nsCOMPtr<nsIDOMFile> >& GetFiles() {
+ const nsTArray<nsRefPtr<DOMFile>>& GetFiles() {
return mFiles;
}
- void SetFiles(const nsTArray<nsCOMPtr<nsIDOMFile> >& aFiles) {
+ void SetFiles(const nsTArray<nsRefPtr<DOMFile>>& aFiles) {
mFiles.Clear();
mFiles.AppendElements(aFiles);
}
HTMLInputElementState()
: mValue()
, mChecked(false)
, mCheckedSet(false)
{};
protected:
~HTMLInputElementState() {}
nsString mValue;
- nsTArray<nsCOMPtr<nsIDOMFile> > mFiles;
+ nsTArray<nsRefPtr<DOMFile>> mFiles;
bool mChecked;
bool mCheckedSet;
};
NS_DEFINE_STATIC_IID_ACCESSOR(HTMLInputElementState, NS_INPUT_ELEMENT_STATE_IID)
NS_IMPL_ISUPPORTS(HTMLInputElementState, HTMLInputElementState)
@@ -311,17 +311,17 @@ UploadLastDir::ContentPrefCallback::Hand
// HandleCompletion is always called (even with HandleError was called),
// so we don't need to do anything special here.
return NS_OK;
}
namespace {
/**
- * This enumerator returns nsDOMFileFile objects after wrapping a single
+ * This enumerator returns DOMFile objects after wrapping a single
* nsIFile representing a directory. It enumerates the files under that
* directory and its subdirectories as a flat list of files, ignoring/skipping
* over symbolic links.
*
* The enumeration involves I/O, so this class must NOT be used on the main
* thread or else the main thread could be blocked for a very long time.
*
* This enumerator does not walk the directory tree breadth-first, but it also
@@ -369,17 +369,19 @@ public:
{
MOZ_ASSERT(!NS_IsMainThread(),
"Walking the directory tree involves I/O, so using this "
"enumerator can block a thread for a long time!");
if (!mNextFile) {
return NS_ERROR_FAILURE;
}
- nsRefPtr<DOMFile> domFile = DOMFile::CreateFromFile(mNextFile);
+
+ // The parent for this object will be set on the main thread.
+ nsRefPtr<DOMFile> domFile = DOMFile::CreateFromFile(nullptr, mNextFile);
nsCString relDescriptor;
nsresult rv =
mNextFile->GetRelativeDescriptor(mTopDirsParent, relDescriptor);
NS_ENSURE_SUCCESS(rv, rv);
NS_ConvertUTF8toUTF16 path(relDescriptor);
nsAutoString leafName;
mNextFile->GetLeafName(leafName);
MOZ_ASSERT(leafName.Length() <= path.Length());
@@ -507,26 +509,26 @@ public:
, mInput(aInput)
, mTopDir(aTopDir)
, mFileListLength(0)
, mCanceled(false)
{}
NS_IMETHOD Run() {
if (!NS_IsMainThread()) {
- // Build up list of nsDOMFileFile objects on this dedicated thread:
+ // Build up list of DOMFile objects on this dedicated thread:
nsCOMPtr<nsISimpleEnumerator> iter =
new DirPickerRecursiveFileEnumerator(mTopDir);
bool hasMore = true;
nsCOMPtr<nsISupports> tmp;
while (NS_SUCCEEDED(iter->HasMoreElements(&hasMore)) && hasMore) {
iter->GetNext(getter_AddRefs(tmp));
nsCOMPtr<nsIDOMFile> domFile = do_QueryInterface(tmp);
MOZ_ASSERT(domFile);
- mFileList.AppendElement(domFile);
+ mFileList.AppendElement(static_cast<DOMFile*>(domFile.get()));
mFileListLength = mFileList.Length();
if (mCanceled) {
MOZ_ASSERT(!mInput, "This is bad - how did this happen?");
// There's no point dispatching to the main thread (that doesn't
// guarantee that we'll be destroyed there).
return NS_OK;
}
}
@@ -546,16 +548,23 @@ public:
mInput->MaybeDispatchProgressEvent(true); // Last progress event.
mInput->mDirPickerFileListBuilderTask = nullptr; // Now null out.
if (mCanceled) { // The last progress event may have canceled us
return NS_OK;
}
+ // Recreate DOMFile with the correct parent object.
+ nsCOMPtr<nsIGlobalObject> global = mInput->OwnerDoc()->GetScopeObject();
+ for (uint32_t i = 0; i < mFileList.Length(); ++i) {
+ MOZ_ASSERT(!mFileList[i]->GetParentObject());
+ mFileList[i] = new DOMFile(global, mFileList[i]->Impl());
+ }
+
// The text control frame (if there is one) isn't going to send a change
// event because it will think this is done by a script.
// So, we can safely send one by ourself.
mInput->SetFiles(mFileList, true);
nsresult rv =
nsContentUtils::DispatchTrustedEvent(mInput->OwnerDoc(),
static_cast<nsIDOMHTMLInputElement*>(mInput.get()),
NS_LITERAL_STRING("change"), true,
@@ -589,17 +598,17 @@ public:
* we don't increase the size of HTMLInputElement for something that's rarely
* used.
*/
uint32_t mPreviousFileListLength;
private:
nsRefPtr<HTMLInputElement> mInput;
nsCOMPtr<nsIFile> mTopDir;
- nsTArray<nsCOMPtr<nsIDOMFile> > mFileList;
+ nsTArray<nsRefPtr<DOMFile>> mFileList;
// We access the list length on both threads, so we need the indirection of
// this atomic member to make the access thread safe:
mozilla::Atomic<uint32_t> mFileListLength;
mozilla::Atomic<bool> mCanceled;
};
@@ -615,17 +624,17 @@ HTMLInputElement::nsFilePickerShownCallb
mInput->CancelDirectoryPickerScanIfRunning();
int16_t mode;
mFilePicker->GetMode(&mode);
if (mode == static_cast<int16_t>(nsIFilePicker::modeGetFolder)) {
// Directory picking is different, since we still need to do more I/O to
- // build up the list of nsDOMFileFile objects. Since this may block for a
+ // build up the list of DOMFile objects. Since this may block for a
// long time, we need to build the list off on another dedicated thread to
// avoid blocking any other activities that the browser is carrying out.
// The user selected this directory, so we always save this dir, even if
// no files are found under it.
nsCOMPtr<nsIFile> pickedDir;
mFilePicker->GetFile(getter_AddRefs(pickedDir));
@@ -650,42 +659,42 @@ HTMLInputElement::nsFilePickerShownCallb
// dispatching the "change" event.
mInput->mDirPickerFileListBuilderTask =
new DirPickerFileListBuilderTask(mInput.get(), pickedDir.get());
return target->Dispatch(mInput->mDirPickerFileListBuilderTask,
NS_DISPATCH_NORMAL);
}
// Collect new selected filenames
- nsTArray<nsCOMPtr<nsIDOMFile> > newFiles;
+ nsTArray<nsRefPtr<DOMFile>> newFiles;
if (mode == static_cast<int16_t>(nsIFilePicker::modeOpenMultiple)) {
nsCOMPtr<nsISimpleEnumerator> iter;
nsresult rv = mFilePicker->GetDomfiles(getter_AddRefs(iter));
NS_ENSURE_SUCCESS(rv, rv);
if (!iter) {
return NS_OK;
}
nsCOMPtr<nsISupports> tmp;
bool hasMore = true;
while (NS_SUCCEEDED(iter->HasMoreElements(&hasMore)) && hasMore) {
iter->GetNext(getter_AddRefs(tmp));
nsCOMPtr<nsIDOMFile> domFile = do_QueryInterface(tmp);
MOZ_ASSERT(domFile);
- newFiles.AppendElement(domFile);
+ newFiles.AppendElement(static_cast<DOMFile*>(domFile.get()));
}
} else {
MOZ_ASSERT(mode == static_cast<int16_t>(nsIFilePicker::modeOpen));
nsCOMPtr<nsIDOMFile> domFile;
nsresult rv = mFilePicker->GetDomfile(getter_AddRefs(domFile));
NS_ENSURE_SUCCESS(rv, rv);
if (domFile) {
- newFiles.AppendElement(domFile);
+ newFiles.AppendElement(static_cast<DOMFile*>(domFile.get()));
}
}
if (newFiles.IsEmpty()) {
return NS_OK;
}
// Store the last used directory using the content pref service:
@@ -931,17 +940,17 @@ HTMLInputElement::InitFilePicker(FilePic
SetFilePickerFiltersFromAccept(filePicker);
} else {
filePicker->AppendFilters(nsIFilePicker::filterAll);
}
// Set default directry and filename
nsAutoString defaultName;
- const nsTArray<nsCOMPtr<nsIDOMFile> >& oldFiles = GetFilesInternal();
+ const nsTArray<nsRefPtr<DOMFile>>& oldFiles = GetFilesInternal();
nsCOMPtr<nsIFilePickerShownCallback> callback =
new HTMLInputElement::nsFilePickerShownCallback(this, filePicker);
if (!oldFiles.IsEmpty() &&
aType != FILE_PICKER_DIRECTORY) {
nsString path;
@@ -1711,17 +1720,17 @@ HTMLInputElement::IsValueEmpty() const
GetValueInternal(value);
return value.IsEmpty();
}
void
HTMLInputElement::ClearFiles(bool aSetValueChanged)
{
- nsTArray<nsCOMPtr<nsIDOMFile> > files;
+ nsTArray<nsRefPtr<DOMFile>> files;
SetFiles(files, aSetValueChanged);
}
/* static */ Decimal
HTMLInputElement::StringToDecimal(const nsAString& aValue)
{
if (!IsASCII(aValue)) {
return Decimal::nan();
@@ -2305,17 +2314,17 @@ HTMLInputElement::MozGetFileNameArray(ui
*aFileNames = ret;
return NS_OK;
}
void
HTMLInputElement::MozSetFileNameArray(const Sequence< nsString >& aFileNames)
{
- nsTArray<nsCOMPtr<nsIDOMFile> > files;
+ nsTArray<nsRefPtr<DOMFile>> files;
for (uint32_t i = 0; i < aFileNames.Length(); ++i) {
nsCOMPtr<nsIFile> file;
if (StringBeginsWith(aFileNames[i], NS_LITERAL_STRING("file:"),
nsASCIICaseInsensitiveStringComparator())) {
// Converts the URL string into the corresponding nsIFile if possible
// A local file will be created if the URL string begins with file://
NS_GetFileFromURLSpec(NS_ConvertUTF16toUTF8(aFileNames[i]),
@@ -2323,17 +2332,18 @@ HTMLInputElement::MozSetFileNameArray(co
}
if (!file) {
// this is no "file://", try as local file
NS_NewLocalFile(aFileNames[i], false, getter_AddRefs(file));
}
if (file) {
- nsCOMPtr<nsIDOMFile> domFile = DOMFile::CreateFromFile(file);
+ nsCOMPtr<nsIGlobalObject> global = OwnerDoc()->GetScopeObject();
+ nsRefPtr<DOMFile> domFile = DOMFile::CreateFromFile(global, file);
files.AppendElement(domFile);
} else {
continue; // Not much we can do if the file doesn't exist
}
}
SetFiles(files, true);
@@ -2559,37 +2569,37 @@ HTMLInputElement::GetDisplayFileName(nsA
nsContentUtils::FormatLocalizedString(nsContentUtils::eFORMS_PROPERTIES,
"XFilesSelected", params, value);
}
aValue = value;
}
void
-HTMLInputElement::SetFiles(const nsTArray<nsCOMPtr<nsIDOMFile> >& aFiles,
+HTMLInputElement::SetFiles(const nsTArray<nsRefPtr<DOMFile>>& aFiles,
bool aSetValueChanged)
{
mFiles.Clear();
mFiles.AppendElements(aFiles);
AfterSetFiles(aSetValueChanged);
}
void
HTMLInputElement::SetFiles(nsIDOMFileList* aFiles,
bool aSetValueChanged)
{
+ nsRefPtr<nsDOMFileList> files = static_cast<nsDOMFileList*>(aFiles);
mFiles.Clear();
if (aFiles) {
uint32_t listLength;
aFiles->GetLength(&listLength);
for (uint32_t i = 0; i < listLength; i++) {
- nsCOMPtr<nsIDOMFile> file;
- aFiles->Item(i, getter_AddRefs(file));
+ nsRefPtr<DOMFile> file = files->Item(i);
mFiles.AppendElement(file);
}
}
AfterSetFiles(aSetValueChanged);
}
void
@@ -2779,17 +2789,17 @@ HTMLInputElement::DispatchProgressEvent(
}
nsresult
HTMLInputElement::UpdateFileList()
{
if (mFileList) {
mFileList->Clear();
- const nsTArray<nsCOMPtr<nsIDOMFile> >& files = GetFilesInternal();
+ const nsTArray<nsRefPtr<DOMFile>>& files = GetFilesInternal();
for (uint32_t i = 0; i < files.Length(); ++i) {
if (!mFileList->Append(files[i])) {
return NS_ERROR_FAILURE;
}
}
}
return NS_OK;
@@ -5629,17 +5639,17 @@ HTMLInputElement::SubmitNamesValues(nsFo
}
//
// Submit file if its input type=file and this encoding method accepts files
//
if (mType == NS_FORM_INPUT_FILE) {
// Submit files
- const nsTArray<nsCOMPtr<nsIDOMFile> >& files = GetFilesInternal();
+ const nsTArray<nsRefPtr<DOMFile>>& files = GetFilesInternal();
for (uint32_t i = 0; i < files.Length(); ++i) {
aFormSubmission->AddNameFilePair(name, files[i], NullString());
}
if (files.IsEmpty()) {
// If no file was selected, pretend we had an empty file with an
// empty filename.
@@ -5877,17 +5887,17 @@ HTMLInputElement::RestoreState(nsPresSta
case VALUE_MODE_DEFAULT_ON:
if (inputState->IsCheckedSet()) {
restoredCheckedState = true;
DoSetChecked(inputState->GetChecked(), true, true);
}
break;
case VALUE_MODE_FILENAME:
{
- const nsTArray<nsCOMPtr<nsIDOMFile> >& files = inputState->GetFiles();
+ const nsTArray<nsRefPtr<DOMFile>>& files = inputState->GetFiles();
SetFiles(files, true);
}
break;
case VALUE_MODE_VALUE:
case VALUE_MODE_DEFAULT:
if (GetValueMode() == VALUE_MODE_DEFAULT &&
mType != NS_FORM_INPUT_HIDDEN) {
break;
@@ -6387,17 +6397,17 @@ HTMLInputElement::IsValueMissing() const
return false;
}
switch (GetValueMode()) {
case VALUE_MODE_VALUE:
return IsValueEmpty();
case VALUE_MODE_FILENAME:
{
- const nsTArray<nsCOMPtr<nsIDOMFile> >& files = GetFilesInternal();
+ const nsTArray<nsRefPtr<DOMFile>>& files = GetFilesInternal();
return files.IsEmpty();
}
case VALUE_MODE_DEFAULT_ON:
// This should not be used for type radio.
// See the MOZ_ASSERT at the beginning of the method.
return !mChecked;
case VALUE_MODE_DEFAULT:
default:
--- a/content/html/content/src/HTMLInputElement.h
+++ b/content/html/content/src/HTMLInputElement.h
@@ -19,30 +19,31 @@
#include "mozilla/dom/HTMLFormElement.h" // for HasEverTriedInvalidSubmit()
#include "mozilla/dom/HTMLInputElementBinding.h"
#include "nsIFilePicker.h"
#include "nsIContentPrefService2.h"
#include "mozilla/Decimal.h"
#include "nsContentUtils.h"
#include "nsTextEditorState.h"
-class nsDOMFileList;
class nsIRadioGroupContainer;
class nsIRadioGroupVisitor;
class nsIRadioVisitor;
namespace mozilla {
class EventChainPostVisitor;
class EventChainPreVisitor;
namespace dom {
class Date;
class DirPickerFileListBuilderTask;
+class DOMFile;
+class nsDOMFileList;
class UploadLastDir MOZ_FINAL : public nsIObserver, public nsSupportsWeakReference {
~UploadLastDir() {}
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIOBSERVER
@@ -205,22 +206,22 @@ public:
NS_IMETHOD_(void) UpdatePlaceholderVisibility(bool aNotify) MOZ_OVERRIDE;
NS_IMETHOD_(bool) GetPlaceholderVisibility() MOZ_OVERRIDE;
NS_IMETHOD_(void) InitializeKeyboardEventListeners() MOZ_OVERRIDE;
NS_IMETHOD_(void) OnValueChanged(bool aNotify) MOZ_OVERRIDE;
NS_IMETHOD_(bool) HasCachedSelection() MOZ_OVERRIDE;
void GetDisplayFileName(nsAString& aFileName) const;
- const nsTArray<nsCOMPtr<nsIDOMFile> >& GetFilesInternal() const
+ const nsTArray<nsRefPtr<DOMFile>>& GetFilesInternal() const
{
return mFiles;
}
- void SetFiles(const nsTArray<nsCOMPtr<nsIDOMFile> >& aFiles, bool aSetValueChanged);
+ void SetFiles(const nsTArray<nsRefPtr<DOMFile>>& aFiles, bool aSetValueChanged);
void SetFiles(nsIDOMFileList* aFiles, bool aSetValueChanged);
// Called when a nsIFilePicker or a nsIColorPicker terminate.
void PickerClosed();
void SetCheckedChangedInternal(bool aCheckedChanged);
bool GetCheckedChanged() const {
return mCheckedChanged;
@@ -1246,17 +1247,17 @@ protected:
* used when uploading a file. It is vital that this is kept separate from
* mValue so that it won't be possible to 'leak' the value from a text-input
* to a file-input. Additionally, the logic for this value is kept as simple
* as possible to avoid accidental errors where the wrong filename is used.
* Therefor the list of filenames is always owned by this member, never by
* the frame. Whenever the frame wants to change the filename it has to call
* SetFileNames to update this member.
*/
- nsTArray<nsCOMPtr<nsIDOMFile> > mFiles;
+ nsTArray<nsRefPtr<DOMFile>> mFiles;
nsRefPtr<nsDOMFileList> mFileList;
nsRefPtr<DirPickerFileListBuilderTask> mDirPickerFileListBuilderTask;
nsString mStaticDocFileList;
/**
--- a/content/html/content/test/test_formData.html
+++ b/content/html/content/test/test_formData.html
@@ -47,22 +47,22 @@ function runTest() {
}
var file, blob = new Blob(['hey'], {type: 'text/plain'});
var fd = new FormData();
fd.append("empty", blob);
fd.append("explicit", blob, "explicit-file-name");
fd.append("explicit-empty", blob, "");
- file = SpecialPowers.unwrap(SpecialPowers.wrap(window).File(blob, {name: 'testname'}));
+ file = new File([blob], 'testname', {type: 'text/plain'});
fd.append("file-name", file);
- file = SpecialPowers.unwrap(SpecialPowers.wrap(window).File(blob, {name: ''}));
+ file = new File([blob], '', {type: 'text/plain'});
fd.append("empty-file-name", file);
- file = SpecialPowers.unwrap(SpecialPowers.wrap(window).File(blob, {name: 'testname'}));
+ file = new File([blob], 'testname', {type: 'text/plain'});
fd.append("file-name-overwrite", file, "overwrite");
xhr.responseType = 'json';
xhr.send(fd);
}
runTest()
</script>
</body>
-</html>
\ No newline at end of file
+</html>
--- a/content/media/EncodedBufferCache.cpp
+++ b/content/media/EncodedBufferCache.cpp
@@ -34,40 +34,42 @@ EncodedBufferCache::AppendBuffer(nsTArra
NS_WARNING("Failed to write media cache block!");
}
}
mEncodedBuffers.Clear();
}
}
-already_AddRefed<nsIDOMBlob>
-EncodedBufferCache::ExtractBlob(const nsAString &aContentType)
+already_AddRefed<dom::DOMFile>
+EncodedBufferCache::ExtractBlob(nsISupports* aParent,
+ const nsAString &aContentType)
{
MutexAutoLock lock(mMutex);
- nsCOMPtr<nsIDOMBlob> blob;
+ nsRefPtr<dom::DOMFile> blob;
if (mTempFileEnabled) {
// generate new temporary file to write
- blob = dom::DOMFile::CreateTemporaryFileBlob(mFD, 0, mDataSize,
+ blob = dom::DOMFile::CreateTemporaryFileBlob(aParent, mFD, 0, mDataSize,
aContentType);
// fallback to memory blob
mTempFileEnabled = false;
mDataSize = 0;
mFD = nullptr;
} else {
void* blobData = moz_malloc(mDataSize);
NS_ASSERTION(blobData, "out of memory!!");
if (blobData) {
for (uint32_t i = 0, offset = 0; i < mEncodedBuffers.Length(); i++) {
memcpy((uint8_t*)blobData + offset, mEncodedBuffers.ElementAt(i).Elements(),
mEncodedBuffers.ElementAt(i).Length());
offset += mEncodedBuffers.ElementAt(i).Length();
}
- blob = dom::DOMFile::CreateMemoryFile(blobData, mDataSize, aContentType);
+ blob = dom::DOMFile::CreateMemoryFile(aParent, blobData, mDataSize,
+ aContentType);
mEncodedBuffers.Clear();
} else
return nullptr;
}
mDataSize = 0;
return blob.forget();
}
--- a/content/media/EncodedBufferCache.h
+++ b/content/media/EncodedBufferCache.h
@@ -11,16 +11,20 @@
#include "nsTArray.h"
#include "mozilla/Mutex.h"
struct PRFileDesc;
class nsIDOMBlob;
namespace mozilla {
+namespace dom {
+class DOMFile;
+}
+
class ReentrantMonitor;
/**
* Data is moved into a temporary file when it grows beyond
* the maximal size passed in the Init function.
* The AppendBuffer and ExtractBlob methods are thread-safe and can be called on
* different threads at the same time.
*/
class EncodedBufferCache
@@ -34,17 +38,17 @@ public:
mTempFileEnabled(false) { }
~EncodedBufferCache()
{
}
// Append buffers in cache, check if the queue is too large then switch to write buffer to file system
// aBuf will append to mEncodedBuffers or temporary File, aBuf also be cleared
void AppendBuffer(nsTArray<uint8_t> & aBuf);
// Read all buffer from memory or file System, also Remove the temporary file or clean the buffers in memory.
- already_AddRefed<nsIDOMBlob> ExtractBlob(const nsAString &aContentType);
+ already_AddRefed<dom::DOMFile> ExtractBlob(nsISupports* aParent, const nsAString &aContentType);
private:
//array for storing the encoded data.
nsTArray<nsTArray<uint8_t> > mEncodedBuffers;
// File handle for the temporary file
PRFileDesc* mFD;
// Used to protect the mEncodedBuffer for avoiding AppendBuffer/Consume on different thread at the same time.
Mutex mMutex;
--- a/content/media/MediaRecorder.cpp
+++ b/content/media/MediaRecorder.cpp
@@ -384,17 +384,18 @@ public:
mTrackUnionStream->ChangeExplicitBlockerCount(-1);
return NS_OK;
}
already_AddRefed<nsIDOMBlob> GetEncodedData()
{
MOZ_ASSERT(NS_IsMainThread());
- return mEncodedBufferCache->ExtractBlob(mMimeType);
+ return mEncodedBufferCache->ExtractBlob(mRecorder->GetParentObject(),
+ mMimeType);
}
bool IsEncoderError()
{
if (mEncoder && mEncoder->HasError()) {
return true;
}
return false;
@@ -915,17 +916,20 @@ MediaRecorder::CreateAndDispatchBlobEven
if (!CheckPrincipal()) {
// Media is not same-origin, don't allow the data out.
nsRefPtr<nsIDOMBlob> blob = aBlob;
return NS_ERROR_DOM_SECURITY_ERR;
}
BlobEventInit init;
init.mBubbles = false;
init.mCancelable = false;
- init.mData = aBlob;
+
+ nsCOMPtr<nsIDOMBlob> blob = aBlob;
+ init.mData = static_cast<DOMFile*>(blob.get());
+
nsRefPtr<BlobEvent> event =
BlobEvent::Constructor(this,
NS_LITERAL_STRING("dataavailable"),
init);
event->SetTrusted(true);
return DispatchDOMEvent(nullptr, event, nullptr, nullptr);
}
--- a/content/media/imagecapture/CaptureTask.cpp
+++ b/content/media/imagecapture/CaptureTask.cpp
@@ -18,16 +18,22 @@ nsresult
CaptureTask::TaskComplete(already_AddRefed<dom::DOMFile> aBlob, nsresult aRv)
{
MOZ_ASSERT(NS_IsMainThread());
DetachStream();
nsresult rv;
nsRefPtr<dom::DOMFile> blob(aBlob);
+
+ // We have to set the parent because the blob has been generated with a valid one.
+ if (blob) {
+ blob = new dom::DOMFile(mImageCapture->GetParentObject(), blob->Impl());
+ }
+
if (mPrincipalChanged) {
aRv = NS_ERROR_DOM_SECURITY_ERR;
IC_LOG("MediaStream principal should not change during TakePhoto().");
}
if (NS_SUCCEEDED(aRv)) {
rv = mImageCapture->PostBlobEvent(blob);
} else {
--- a/content/media/imagecapture/ImageCapture.cpp
+++ b/content/media/imagecapture/ImageCapture.cpp
@@ -167,17 +167,17 @@ ImageCapture::TakePhoto(ErrorResult& aRe
// It adds itself into MediaStreamGraph, so ImageCapture doesn't need to hold
// the reference.
task->AttachStream();
}
}
nsresult
-ImageCapture::PostBlobEvent(nsIDOMBlob* aBlob)
+ImageCapture::PostBlobEvent(DOMFile* aBlob)
{
MOZ_ASSERT(NS_IsMainThread());
if (!CheckPrincipal()) {
// Media is not same-origin, don't allow the data out.
return PostErrorEvent(ImageCaptureError::PHOTO_ERROR, NS_ERROR_DOM_SECURITY_ERR);
}
BlobEventInit init;
--- a/content/media/imagecapture/ImageCapture.h
+++ b/content/media/imagecapture/ImageCapture.h
@@ -27,16 +27,17 @@ PRLogModuleInfo* GetICLog();
#ifndef IC_LOG
#define IC_LOG(...)
#endif
#endif // PR_LOGGING
namespace dom {
+class DOMFile;
class VideoStreamTrack;
/**
* Implementation of https://dvcs.w3.org/hg/dap/raw-file/default/media-stream-
* capture/ImageCapture.html.
* The ImageCapture accepts a VideoStreamTrack as input source. The image will
* be sent back as a JPG format via Blob event.
*
@@ -74,17 +75,17 @@ public:
static already_AddRefed<ImageCapture> Constructor(const GlobalObject& aGlobal,
VideoStreamTrack& aTrack,
ErrorResult& aRv);
ImageCapture(VideoStreamTrack* aVideoStreamTrack, nsPIDOMWindow* aOwnerWindow);
// Post a Blob event to script.
- nsresult PostBlobEvent(nsIDOMBlob* aBlob);
+ nsresult PostBlobEvent(DOMFile* aBlob);
// Post an error event to script.
// aErrorCode should be one of error codes defined in ImageCaptureError.h.
// aReason is the nsresult which maps to a error string in dom/base/domerr.msg.
nsresult PostErrorEvent(uint16_t aErrorCode, nsresult aReason = NS_OK);
bool CheckPrincipal();
--- a/content/media/webrtc/MediaEngineDefault.cpp
+++ b/content/media/webrtc/MediaEngineDefault.cpp
@@ -203,17 +203,17 @@ MediaEngineDefaultVideoSource::Snapshot(
nsCOMPtr<nsIFile> localFile;
filePicker->GetFile(getter_AddRefs(localFile));
if (!localFile) {
*aFile = nullptr;
return NS_OK;
}
- nsCOMPtr<nsIDOMFile> domFile = dom::DOMFile::CreateFromFile(localFile);
+ nsCOMPtr<nsIDOMFile> domFile = dom::DOMFile::CreateFromFile(nullptr, localFile);
domFile.forget(aFile);
return NS_OK;
#endif
}
NS_IMETHODIMP
MediaEngineDefaultVideoSource::Notify(nsITimer* aTimer)
{
--- a/content/media/webrtc/MediaEngineWebRTCVideo.cpp
+++ b/content/media/webrtc/MediaEngineWebRTCVideo.cpp
@@ -939,17 +939,17 @@ MediaEngineWebRTCVideoSource::OnTakePict
mCallbacks.SwapElements(aCallbacks);
mPhoto.AppendElements(aData, aLength);
mMimeType = aMimeType;
}
NS_IMETHOD Run()
{
nsRefPtr<dom::DOMFile> blob =
- dom::DOMFile::CreateMemoryFile(mPhoto.Elements(), mPhoto.Length(), mMimeType);
+ dom::DOMFile::CreateMemoryFile(nullptr, mPhoto.Elements(), mPhoto.Length(), mMimeType);
uint32_t callbackCounts = mCallbacks.Length();
for (uint8_t i = 0; i < callbackCounts; i++) {
nsRefPtr<dom::DOMFile> tempBlob = blob;
mCallbacks[i]->PhotoComplete(tempBlob.forget());
}
// PhotoCallback needs to dereference on main thread.
mCallbacks.Clear();
return NS_OK;
--- a/dom/archivereader/ArchiveReader.cpp
+++ b/dom/archivereader/ArchiveReader.cpp
@@ -4,36 +4,35 @@
* 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 "ArchiveReader.h"
#include "ArchiveRequest.h"
#include "ArchiveEvent.h"
#include "ArchiveZipEvent.h"
+#include "nsDOMFile.h"
#include "nsIURI.h"
#include "nsNetUtil.h"
#include "mozilla/dom/ArchiveReaderBinding.h"
#include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/Preferences.h"
#include "mozilla/dom/EncodingUtils.h"
using namespace mozilla;
using namespace mozilla::dom;
USING_ARCHIVEREADER_NAMESPACE
/* static */ already_AddRefed<ArchiveReader>
ArchiveReader::Constructor(const GlobalObject& aGlobal,
- nsIDOMBlob* aBlob,
+ DOMFile& aBlob,
const ArchiveReaderOptions& aOptions,
ErrorResult& aError)
{
- MOZ_ASSERT(aBlob);
-
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aGlobal.GetAsSupports());
if (!window) {
aError.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
}
nsAutoCString encoding;
if (!EncodingUtils::FindEncodingForLabelNoReplacement(aOptions.mEncoding,
@@ -42,24 +41,23 @@ ArchiveReader::Constructor(const GlobalO
return nullptr;
}
nsRefPtr<ArchiveReader> reader =
new ArchiveReader(aBlob, window, encoding);
return reader.forget();
}
-ArchiveReader::ArchiveReader(nsIDOMBlob* aBlob, nsPIDOMWindow* aWindow,
+ArchiveReader::ArchiveReader(DOMFile& aBlob, nsPIDOMWindow* aWindow,
const nsACString& aEncoding)
- : mBlob(aBlob)
+ : mBlob(&aBlob)
, mWindow(aWindow)
, mStatus(NOT_STARTED)
, mEncoding(aEncoding)
{
- MOZ_ASSERT(aBlob);
MOZ_ASSERT(aWindow);
}
ArchiveReader::~ArchiveReader()
{
}
/* virtual */ JSObject*
--- a/dom/archivereader/ArchiveReader.h
+++ b/dom/archivereader/ArchiveReader.h
@@ -14,16 +14,17 @@
#include "nsCOMArray.h"
#include "nsIChannel.h"
#include "nsIDOMFile.h"
#include "mozilla/Attributes.h"
namespace mozilla {
namespace dom {
struct ArchiveReaderOptions;
+class DOMFile;
class GlobalObject;
} // namespace dom
} // namespace mozilla
BEGIN_ARCHIVEREADER_NAMESPACE
class ArchiveRequest;
@@ -33,20 +34,20 @@ class ArchiveRequest;
class ArchiveReader MOZ_FINAL : public nsISupports,
public nsWrapperCache
{
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(ArchiveReader)
static already_AddRefed<ArchiveReader>
- Constructor(const GlobalObject& aGlobal, nsIDOMBlob* aBlob,
+ Constructor(const GlobalObject& aGlobal, DOMFile& aBlob,
const ArchiveReaderOptions& aOptions, ErrorResult& aError);
- ArchiveReader(nsIDOMBlob* aBlob, nsPIDOMWindow* aWindow,
+ ArchiveReader(DOMFile& aBlob, nsPIDOMWindow* aWindow,
const nsACString& aEncoding);
nsIDOMWindow* GetParentObject() const
{
return mWindow;
}
virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
@@ -70,17 +71,17 @@ private:
already_AddRefed<ArchiveRequest> GenerateArchiveRequest();
nsresult OpenArchive();
void RequestReady(ArchiveRequest* aRequest);
protected:
// The archive blob/file
- nsCOMPtr<nsIDOMBlob> mBlob;
+ nsRefPtr<DOMFile> mBlob;
// The window is needed by the requests
nsCOMPtr<nsPIDOMWindow> mWindow;
// Are we ready to return data?
enum {
NOT_STARTED = 0,
WORKING,
--- a/dom/archivereader/ArchiveZipEvent.cpp
+++ b/dom/archivereader/ArchiveZipEvent.cpp
@@ -79,17 +79,17 @@ nsIDOMFile*
ArchiveZipItem::File(ArchiveReader* aArchiveReader)
{
nsString filename;
if (NS_FAILED(GetFilename(filename))) {
return nullptr;
}
- return new DOMFile(
+ return new DOMFile(aArchiveReader,
new ArchiveZipFileImpl(filename,
NS_ConvertUTF8toUTF16(GetType()),
StrToInt32(mCentralStruct.orglen),
mCentralStruct, aArchiveReader));
}
uint32_t
ArchiveZipItem::StrToInt32(const uint8_t* aStr)
--- a/dom/archivereader/ArchiveZipFile.cpp
+++ b/dom/archivereader/ArchiveZipFile.cpp
@@ -2,20 +2,22 @@
/* vim: set ts=2 et sw=2 tw=80: */
/* 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 "ArchiveZipFile.h"
#include "ArchiveZipEvent.h"
+#include "nsDOMFile.h"
#include "nsIInputStream.h"
#include "zlib.h"
#include "mozilla/Attributes.h"
+using namespace mozilla::dom;
USING_ARCHIVEREADER_NAMESPACE
#define ZIP_CHUNK 16384
/**
* Input stream object for zip files
*/
class ArchiveInputStream MOZ_FINAL : public nsIInputStream,
@@ -394,17 +396,18 @@ ArchiveZipFileImpl::Traverse(nsCycleColl
{
ArchiveZipFileImpl* tmp = this;
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mArchiveReader);
}
already_AddRefed<mozilla::dom::DOMFileImpl>
ArchiveZipFileImpl::CreateSlice(uint64_t aStart,
uint64_t aLength,
- const nsAString& aContentType)
+ const nsAString& aContentType,
+ ErrorResult& aRv)
{
nsRefPtr<DOMFileImpl> impl =
new ArchiveZipFileImpl(mFilename, mContentType, aStart, mLength, mCentral,
mArchiveReader);
return impl.forget();
}
NS_IMPL_ISUPPORTS_INHERITED0(ArchiveZipFileImpl, DOMFileImpl)
--- a/dom/archivereader/ArchiveZipFile.h
+++ b/dom/archivereader/ArchiveZipFile.h
@@ -66,19 +66,19 @@ public:
}
protected:
virtual ~ArchiveZipFileImpl()
{
MOZ_COUNT_DTOR(ArchiveZipFileImpl);
}
- virtual already_AddRefed<DOMFileImpl> CreateSlice(uint64_t aStart,
- uint64_t aLength,
- const nsAString& aContentType) MOZ_OVERRIDE;
+ virtual already_AddRefed<DOMFileImpl>
+ CreateSlice(uint64_t aStart, uint64_t aLength, const nsAString& aContentType,
+ ErrorResult& aRv) MOZ_OVERRIDE;
private: // Data
ZipCentral mCentral;
nsRefPtr<ArchiveReader> mArchiveReader;
nsString mFilename;
};
--- a/dom/base/ImageEncoder.cpp
+++ b/dom/base/ImageEncoder.cpp
@@ -83,18 +83,20 @@ public:
{}
NS_IMETHOD Run()
{
nsresult rv = NS_OK;
MOZ_ASSERT(NS_IsMainThread());
if (!mFailed) {
+ // The correct parentObject has to be set by the mEncodeCompleteCallback.
nsRefPtr<DOMFile> blob =
- DOMFile::CreateMemoryFile(mImgData, mImgSize, mType);
+ DOMFile::CreateMemoryFile(nullptr, mImgData, mImgSize, mType);
+ MOZ_ASSERT(blob);
rv = mEncodeCompleteCallback->ReceiveBlob(blob.forget());
}
mEncodeCompleteCallback = nullptr;
mEncoderThread->Shutdown();
return rv;
--- a/dom/base/ImageEncoder.h
+++ b/dom/base/ImageEncoder.h
@@ -46,27 +46,31 @@ public:
// fall back to a PNG encoder. aOptions are the options to be passed to the
// encoder and aUsingCustomOptions specifies whether custom parse options were
// used (i.e. by using -moz-parse-options). If there are any unrecognized
// custom parse options, we fall back to the default values for the encoder
// without any options at all. A return value of NS_OK only implies
// successful dispatching of the extraction step to the encoding thread.
// aEncodeCallback will be called on main thread when encoding process is
// success.
+ // Note: The callback has to set a valid parent for content for the generated
+ // Blob object.
static nsresult ExtractDataAsync(nsAString& aType,
const nsAString& aOptions,
bool aUsingCustomOptions,
uint8_t* aImageBuffer,
int32_t aFormat,
const nsIntSize aSize,
EncodeCompleteCallback* aEncodeCallback);
// Extract an Image asynchronously. Its function is same as ExtractDataAsync
// except for the parameters. aImage is the uncompressed data. aEncodeCallback
// will be called on main thread when encoding process is success.
+ // Note: The callback has to set a valid parent for content for the generated
+ // Blob object.
static nsresult ExtractDataFromLayersImageAsync(nsAString& aType,
const nsAString& aOptions,
bool aUsingCustomOptions,
layers::Image* aImage,
EncodeCompleteCallback* aEncodeCallback);
// Gives you a stream containing the image represented by aImageBuffer.
// The format is given in aFormat, for example
--- a/dom/base/MessagePort.cpp
+++ b/dom/base/MessagePort.cpp
@@ -1,27 +1,28 @@
/* -*- 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 "MessagePort.h"
#include "MessageEvent.h"
+#include "mozilla/dom/BlobBinding.h"
#include "mozilla/dom/Event.h"
#include "mozilla/dom/MessageChannel.h"
#include "mozilla/dom/MessagePortBinding.h"
#include "mozilla/dom/MessagePortList.h"
#include "mozilla/dom/StructuredCloneTags.h"
#include "nsContentUtils.h"
+#include "nsDOMFile.h"
#include "nsGlobalWindow.h"
#include "nsPresContext.h"
#include "ScriptSettings.h"
#include "nsIDocument.h"
-#include "nsIDOMFile.h"
#include "nsIDOMFileList.h"
#include "nsIPresShell.h"
namespace mozilla {
namespace dom {
class DispatchEventRunnable : public nsRunnable
{
@@ -98,17 +99,47 @@ struct StructuredCloneInfo
static JSObject*
PostMessageReadStructuredClone(JSContext* cx,
JSStructuredCloneReader* reader,
uint32_t tag,
uint32_t data,
void* closure)
{
- if (tag == SCTAG_DOM_BLOB || tag == SCTAG_DOM_FILELIST) {
+ StructuredCloneInfo* scInfo = static_cast<StructuredCloneInfo*>(closure);
+ NS_ASSERTION(scInfo, "Must have scInfo!");
+
+ if (tag == SCTAG_DOM_BLOB) {
+ NS_ASSERTION(!data, "Data should be empty");
+
+ // What we get back from the reader is a DOMFileImpl.
+ // From that we create a new DOMFile.
+ DOMFileImpl* blobImpl;
+ if (JS_ReadBytes(reader, &blobImpl, sizeof(blobImpl))) {
+ MOZ_ASSERT(blobImpl);
+
+ // nsRefPtr<DOMFile> needs to go out of scope before toObjectOrNull() is
+ // called because the static analysis thinks dereferencing XPCOM objects
+ // can GC (because in some cases it can!), and a return statement with a
+ // JSObject* type means that JSObject* is on the stack as a raw pointer
+ // while destructors are running.
+ JS::Rooted<JS::Value> val(cx);
+ {
+ nsRefPtr<DOMFile> blob = new DOMFile(scInfo->mPort->GetParentObject(),
+ blobImpl);
+ if (!WrapNewBindingObject(cx, blob, &val)) {
+ return nullptr;
+ }
+ }
+
+ return &val.toObject();
+ }
+ }
+
+ if (tag == SCTAG_DOM_FILELIST) {
NS_ASSERTION(!data, "Data should be empty");
nsISupports* supports;
if (JS_ReadBytes(reader, &supports, sizeof(supports))) {
JS::Rooted<JS::Value> val(cx);
if (NS_SUCCEEDED(nsContentUtils::WrapNative(cx, supports, &val))) {
return val.toObjectOrNull();
}
@@ -129,28 +160,36 @@ static bool
PostMessageWriteStructuredClone(JSContext* cx,
JSStructuredCloneWriter* writer,
JS::Handle<JSObject*> obj,
void *closure)
{
StructuredCloneInfo* scInfo = static_cast<StructuredCloneInfo*>(closure);
NS_ASSERTION(scInfo, "Must have scInfo!");
+ // See if this is a File/Blob object.
+ {
+ DOMFile* blob = nullptr;
+ if (NS_SUCCEEDED(UNWRAP_OBJECT(Blob, obj, blob))) {
+ DOMFileImpl* blobImpl = blob->Impl();
+ if (JS_WriteUint32Pair(writer, SCTAG_DOM_BLOB, 0) &&
+ JS_WriteBytes(writer, &blobImpl, sizeof(blobImpl))) {
+ scInfo->mEvent->StoreISupports(blobImpl);
+ return true;
+ }
+ }
+ }
+
nsCOMPtr<nsIXPConnectWrappedNative> wrappedNative;
nsContentUtils::XPConnect()->
GetWrappedNativeOfJSObject(cx, obj, getter_AddRefs(wrappedNative));
if (wrappedNative) {
uint32_t scTag = 0;
nsISupports* supports = wrappedNative->Native();
- nsCOMPtr<nsIDOMBlob> blob = do_QueryInterface(supports);
- if (blob) {
- scTag = SCTAG_DOM_BLOB;
- }
-
nsCOMPtr<nsIDOMFileList> list = do_QueryInterface(supports);
if (list) {
scTag = SCTAG_DOM_FILELIST;
}
if (scTag) {
return JS_WriteUint32Pair(writer, scTag, 0) &&
JS_WriteBytes(writer, &supports, sizeof(supports)) &&
--- a/dom/base/Navigator.cpp
+++ b/dom/base/Navigator.cpp
@@ -8,16 +8,17 @@
#include "base/basictypes.h"
#include "Navigator.h"
#include "nsIXULAppInfo.h"
#include "nsPluginArray.h"
#include "nsMimeTypeArray.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/dom/DesktopNotification.h"
+#include "nsDOMFile.h"
#include "nsGeolocation.h"
#include "nsIHttpProtocolHandler.h"
#include "nsIContentPolicy.h"
#include "nsIContentSecurityPolicy.h"
#include "nsContentPolicyUtils.h"
#include "nsCrossSiteListenerProxy.h"
#include "nsISupportsPriority.h"
#include "nsICachingChannel.h"
@@ -1150,24 +1151,24 @@ Navigator::SendBeacon(const nsAString& a
if (NS_FAILED(rv)) {
aRv.Throw(NS_ERROR_FAILURE);
return false;
}
mimeType.AssignLiteral("application/octet-stream");
in = strStream;
} else if (aData.Value().IsBlob()) {
- nsCOMPtr<nsIDOMBlob> blob = aData.Value().GetAsBlob();
- rv = blob->GetInternalStream(getter_AddRefs(in));
+ DOMFile& blob = aData.Value().GetAsBlob();
+ rv = blob.GetInternalStream(getter_AddRefs(in));
if (NS_FAILED(rv)) {
aRv.Throw(NS_ERROR_FAILURE);
return false;
}
nsAutoString type;
- rv = blob->GetType(type);
+ rv = blob.GetType(type);
if (NS_FAILED(rv)) {
aRv.Throw(NS_ERROR_FAILURE);
return false;
}
mimeType = NS_ConvertUTF16toUTF8(type);
} else if (aData.Value().IsFormData()) {
nsFormData& form = aData.Value().GetAsFormData();
--- a/dom/base/Navigator.h
+++ b/dom/base/Navigator.h
@@ -20,17 +20,16 @@
#include "nsTArray.h"
class nsPluginArray;
class nsMimeTypeArray;
class nsPIDOMWindow;
class nsIDOMNavigatorSystemMessages;
class nsDOMCameraManager;
class nsDOMDeviceStorage;
-class nsIDOMBlob;
class nsIPrincipal;
class nsIURI;
namespace mozilla {
namespace dom {
class Geolocation;
class systemMessageCallback;
struct MediaStreamConstraints;
--- a/dom/base/URL.cpp
+++ b/dom/base/URL.cpp
@@ -106,25 +106,22 @@ URL::Constructor(const GlobalObject& aGl
}
nsRefPtr<URL> url = new URL(uri);
return url.forget();
}
void
URL::CreateObjectURL(const GlobalObject& aGlobal,
- nsIDOMBlob* aBlob,
+ DOMFile& aBlob,
const objectURLOptions& aOptions,
nsString& aResult,
ErrorResult& aError)
{
- DOMFile* blob = static_cast<DOMFile*>(aBlob);
- MOZ_ASSERT(blob);
-
- CreateObjectURLInternal(aGlobal, blob->Impl(),
+ CreateObjectURLInternal(aGlobal, aBlob.Impl(),
NS_LITERAL_CSTRING(BLOBURI_SCHEME), aOptions, aResult,
aError);
}
void
URL::CreateObjectURL(const GlobalObject& aGlobal, DOMMediaStream& aStream,
const mozilla::dom::objectURLOptions& aOptions,
nsString& aResult,
--- a/dom/base/URL.h
+++ b/dom/base/URL.h
@@ -18,16 +18,17 @@ class nsIURI;
namespace mozilla {
class ErrorResult;
class DOMMediaStream;
namespace dom {
+class DOMFile;
class MediaSource;
class GlobalObject;
struct objectURLOptions;
namespace workers {
class URLProxy;
}
@@ -48,17 +49,17 @@ public:
static already_AddRefed<URL>
Constructor(const GlobalObject& aGlobal, const nsAString& aUrl,
URL& aBase, ErrorResult& aRv);
static already_AddRefed<URL>
Constructor(const GlobalObject& aGlobal, const nsAString& aUrl,
const nsAString& aBase, ErrorResult& aRv);
static void CreateObjectURL(const GlobalObject& aGlobal,
- nsIDOMBlob* aBlob,
+ DOMFile& aBlob,
const objectURLOptions& aOptions,
nsString& aResult,
ErrorResult& aError);
static void CreateObjectURL(const GlobalObject& aGlobal,
DOMMediaStream& aStream,
const objectURLOptions& aOptions,
nsString& aResult,
ErrorResult& aError);
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -96,20 +96,16 @@
#include "nsITreeSelection.h"
#include "nsITreeContentView.h"
#include "nsITreeView.h"
#include "nsIXULTemplateBuilder.h"
#include "nsITreeColumns.h"
#endif
#include "nsIDOMXPathNSResolver.h"
-// Drag and drop
-#include "nsIDOMFile.h"
-#include "nsDOMBlobBuilder.h" // nsDOMMultipartFile
-
#include "nsIEventListenerService.h"
#include "nsIMessageManager.h"
#include "mozilla/dom/TouchEvent.h"
#include "nsWrapperCacheInlines.h"
#include "mozilla/dom/HTMLCollectionBinding.h"
@@ -289,21 +285,16 @@ static nsDOMClassInfoData sClassInfoData
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(XSLTProcessor, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(XPathNSResolver, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
- NS_DEFINE_CLASSINFO_DATA(Blob, nsDOMGenericSH,
- DOM_DEFAULT_SCRIPTABLE_FLAGS)
- NS_DEFINE_CLASSINFO_DATA(File, nsDOMGenericSH,
- DOM_DEFAULT_SCRIPTABLE_FLAGS)
-
NS_DEFINE_CLASSINFO_DATA(MozSmsMessage, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(MozMmsMessage, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(MozMobileMessageThread, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
@@ -367,18 +358,16 @@ struct nsConstructorFuncMapData
nsDOMConstructorFunc mConstructorFunc;
};
#define NS_DEFINE_CONSTRUCTOR_FUNC_DATA(_class, _func) \
{ eDOMClassInfo_##_class##_id, _func },
static const nsConstructorFuncMapData kConstructorFuncMap[] =
{
- NS_DEFINE_CONSTRUCTOR_FUNC_DATA(Blob, DOMMultipartFileImpl::NewBlob)
- NS_DEFINE_CONSTRUCTOR_FUNC_DATA(File, DOMMultipartFileImpl::NewFile)
NS_DEFINE_CONSTRUCTOR_FUNC_DATA(XSLTProcessor, XSLTProcessorCtor)
};
#undef NS_DEFINE_CONSTRUCTOR_FUNC_DATA
nsIXPConnect *nsDOMClassInfo::sXPConnect = nullptr;
bool nsDOMClassInfo::sIsInitialized = false;
@@ -790,25 +779,16 @@ nsDOMClassInfo::Init()
DOM_CLASSINFO_MAP_ENTRY(nsIXSLTProcessor)
DOM_CLASSINFO_MAP_ENTRY(nsIXSLTProcessorPrivate)
DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN(XPathNSResolver, nsIDOMXPathNSResolver)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMXPathNSResolver)
DOM_CLASSINFO_MAP_END
- DOM_CLASSINFO_MAP_BEGIN(Blob, nsIDOMBlob)
- DOM_CLASSINFO_MAP_ENTRY(nsIDOMBlob)
- DOM_CLASSINFO_MAP_END
-
- DOM_CLASSINFO_MAP_BEGIN(File, nsIDOMFile)
- DOM_CLASSINFO_MAP_ENTRY(nsIDOMBlob)
- DOM_CLASSINFO_MAP_ENTRY(nsIDOMFile)
- DOM_CLASSINFO_MAP_END
-
DOM_CLASSINFO_MAP_BEGIN(MozSmsMessage, nsIDOMMozSmsMessage)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMMozSmsMessage)
DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN(MozMmsMessage, nsIDOMMozMmsMessage)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMMozMmsMessage)
DOM_CLASSINFO_MAP_END
--- a/dom/base/nsDOMClassInfoClasses.h
+++ b/dom/base/nsDOMClassInfoClasses.h
@@ -38,19 +38,16 @@ DOMCI_CLASS(CSSMozDocumentRule)
DOMCI_CLASS(CSSSupportsRule)
// XSLTProcessor
DOMCI_CLASS(XSLTProcessor)
// DOM Level 3 XPath objects
DOMCI_CLASS(XPathNSResolver)
-DOMCI_CLASS(Blob)
-DOMCI_CLASS(File)
-
DOMCI_CLASS(MozSmsMessage)
DOMCI_CLASS(MozMmsMessage)
DOMCI_CLASS(MozMobileMessageThread)
// @font-face in CSS
DOMCI_CLASS(CSSFontFaceRule)
DOMCI_CLASS(ContentFrameMessageManager)
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -2848,17 +2848,25 @@ nsDOMWindowUtils::WrapDOMFile(nsIFile *a
nsIDOMFile **aDOMFile)
{
MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
if (!aFile) {
return NS_ERROR_FAILURE;
}
- nsRefPtr<DOMFile> file = DOMFile::CreateFromFile(aFile);
+ nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
+ NS_ENSURE_STATE(window);
+
+ nsPIDOMWindow* innerWindow = window->GetCurrentInnerWindow();
+ if (!innerWindow) {
+ return NS_ERROR_FAILURE;
+ }
+
+ nsRefPtr<DOMFile> file = DOMFile::CreateFromFile(innerWindow, aFile);
file.forget(aDOMFile);
return NS_OK;
}
#ifdef DEBUG
static bool
CheckLeafLayers(Layer* aLayer, const nsIntPoint& aOffset, nsIntRegion* aCoveredRegion)
{
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -7873,28 +7873,42 @@ struct StructuredCloneInfo {
static JSObject*
PostMessageReadStructuredClone(JSContext* cx,
JSStructuredCloneReader* reader,
uint32_t tag,
uint32_t data,
void* closure)
{
+ StructuredCloneInfo* scInfo = static_cast<StructuredCloneInfo*>(closure);
+ NS_ASSERTION(scInfo, "Must have scInfo!");
+
if (tag == SCTAG_DOM_BLOB) {
NS_ASSERTION(!data, "Data should be empty");
// What we get back from the reader is a DOMFileImpl.
// From that we create a new DOMFile.
- nsISupports* supports;
- if (JS_ReadBytes(reader, &supports, sizeof(supports))) {
- nsCOMPtr<nsIDOMBlob> file = new DOMFile(static_cast<DOMFileImpl*>(supports));
+ DOMFileImpl* blobImpl;
+ if (JS_ReadBytes(reader, &blobImpl, sizeof(blobImpl))) {
+ MOZ_ASSERT(blobImpl);
+
+ // nsRefPtr<DOMFile> needs to go out of scope before toObjectOrNull() is
+ // called because the static analysis thinks dereferencing XPCOM objects
+ // can GC (because in some cases it can!), and a return statement with a
+ // JSObject* type means that JSObject* is on the stack as a raw pointer
+ // while destructors are running.
JS::Rooted<JS::Value> val(cx);
- if (NS_SUCCEEDED(nsContentUtils::WrapNative(cx, file, &val))) {
- return val.toObjectOrNull();
- }
+ {
+ nsRefPtr<DOMFile> blob = new DOMFile(scInfo->window, blobImpl);
+ if (!WrapNewBindingObject(cx, blob, &val)) {
+ return nullptr;
+ }
+ }
+
+ return &val.toObject();
}
}
if (tag == SCTAG_DOM_FILELIST) {
NS_ASSERTION(!data, "Data should be empty");
nsISupports* supports;
if (JS_ReadBytes(reader, &supports, sizeof(supports))) {
@@ -7919,30 +7933,36 @@ static bool
PostMessageWriteStructuredClone(JSContext* cx,
JSStructuredCloneWriter* writer,
JS::Handle<JSObject*> obj,
void *closure)
{
StructuredCloneInfo* scInfo = static_cast<StructuredCloneInfo*>(closure);
NS_ASSERTION(scInfo, "Must have scInfo!");
+ // See if this is a File/Blob object.
+ {
+ DOMFile* blob = nullptr;
+ if (scInfo->subsumes && NS_SUCCEEDED(UNWRAP_OBJECT(Blob, obj, blob))) {
+ DOMFileImpl* blobImpl = blob->Impl();
+ if (JS_WriteUint32Pair(writer, SCTAG_DOM_BLOB, 0) &&
+ JS_WriteBytes(writer, &blobImpl, sizeof(blobImpl))) {
+ scInfo->event->StoreISupports(blobImpl);
+ return true;
+ }
+ }
+ }
+
nsCOMPtr<nsIXPConnectWrappedNative> wrappedNative;
nsContentUtils::XPConnect()->
GetWrappedNativeOfJSObject(cx, obj, getter_AddRefs(wrappedNative));
if (wrappedNative) {
uint32_t scTag = 0;
nsISupports* supports = wrappedNative->Native();
- nsCOMPtr<nsIDOMBlob> blob = do_QueryInterface(supports);
- if (blob && scInfo->subsumes) {
- scTag = SCTAG_DOM_BLOB;
- DOMFile* file = static_cast<DOMFile*>(blob.get());
- supports = file->Impl();
- }
-
nsCOMPtr<nsIDOMFileList> list = do_QueryInterface(supports);
if (list && scInfo->subsumes)
scTag = SCTAG_DOM_FILELIST;
if (scTag)
return JS_WriteUint32Pair(writer, scTag, 0) &&
JS_WriteBytes(writer, &supports, sizeof(supports)) &&
scInfo->event->StoreISupports(supports);
--- a/dom/base/test/file_url.jsm
+++ b/dom/base/test/file_url.jsm
@@ -1,12 +1,12 @@
this.EXPORTED_SYMBOLS = ['checkFromJSM'];
this.checkFromJSM = function checkFromJSM(ok, is) {
- Components.utils.importGlobalProperties(['URL']);
+ Components.utils.importGlobalProperties(['URL', 'Blob']);
var url = new URL('http://www.example.com');
is(url.href, "http://www.example.com/", "JSM should have URL");
var url2 = new URL('/foobar', url);
is(url2.href, "http://www.example.com/foobar", "JSM should have URL - based on another URL");
var blob = new Blob(['a']);
--- a/dom/base/test/test_messageChannel_post.html
+++ b/dom/base/test/test_messageChannel_post.html
@@ -45,17 +45,21 @@ https://bugzilla.mozilla.org/show_bug.cg
null,
undefined,
"hello world",
new Blob([]),
true ];
a.port1.onmessage = function(evt) {
ok(tests.length, "We are waiting for a message");
- is(tests[0], evt.data, "Value ok: " + tests[0]);
+ if (typeof(tests[0]) == 'object') {
+ is(typeof(tests[0]), typeof(evt.data), "Value ok: " + tests[0]);
+ } else {
+ is(tests[0], evt.data, "Value ok: " + tests[0]);
+ }
tests.shift();
runTest();
}
function runTest() {
if (!tests.length) {
SimpleTest.finish();
return;
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -131,23 +131,20 @@ DOMInterfaces = {
'channelInterpretation': 'channelInterpretationValue',
},
},
'BarProp': {
'headerFile': 'mozilla/dom/BarProps.h',
},
-'Blob': [
-{
- 'headerFile': 'nsIDOMFile.h',
+'Blob': {
+ 'nativeType': 'mozilla::dom::DOMFile',
+ 'headerFile': 'nsDOMFile.h',
},
-{
- 'workers': True,
-}],
'BatteryManager': {
'nativeType': 'mozilla::dom::battery::BatteryManager',
'headerFile': 'BatteryManager.h'
},
'BluetoothAdapter': {
'nativeType': 'mozilla::dom::bluetooth::BluetoothAdapter',
@@ -398,18 +395,23 @@ DOMInterfaces = {
'Exception': {
'headerFile': 'mozilla/dom/DOMException.h',
'binaryNames': {
'message': 'messageMoz',
},
},
+'File': {
+ 'nativeType': 'mozilla::dom::DOMFile',
+ 'headerFile': 'nsDOMFile.h',
+},
+
'FileList': {
- 'nativeType': 'nsDOMFileList',
+ 'nativeType': 'mozilla::dom::nsDOMFileList',
'headerFile': 'nsDOMFile.h',
},
'FileReader': {
'nativeType': 'nsDOMFileReader',
'implicitJSContext': [ 'readAsArrayBuffer' ],
},
@@ -1793,17 +1795,16 @@ def addExternalIface(iface, nativeType=N
domInterface['headerFile'] = headerFile
domInterface['notflattened'] = notflattened
DOMInterfaces[iface] = domInterface
addExternalIface('ApplicationCache', nativeType='nsIDOMOfflineResourceList')
addExternalIface('Counter')
addExternalIface('CSSRule')
addExternalIface('RTCDataChannel', nativeType='nsIDOMDataChannel')
-addExternalIface('File')
addExternalIface('HitRegionOptions', nativeType='nsISupports')
addExternalIface('imgINotificationObserver', nativeType='imgINotificationObserver')
addExternalIface('imgIRequest', nativeType='imgIRequest', notflattened=True)
addExternalIface('MenuBuilder', nativeType='nsIMenuBuilder', notflattened=True)
addExternalIface('MozBoxObject', nativeType='nsIBoxObject')
addExternalIface('MozControllers', nativeType='nsIControllers')
addExternalIface('MozFrameLoader', nativeType='nsIFrameLoader', notflattened=True)
addExternalIface('MozFrameRequestCallback', nativeType='nsIFrameRequestCallback',
@@ -1822,16 +1823,17 @@ addExternalIface('MozWakeLockListener',
addExternalIface('MozXULTemplateBuilder', nativeType='nsIXULTemplateBuilder')
addExternalIface('nsIBrowserDOMWindow', nativeType='nsIBrowserDOMWindow',
notflattened=True)
addExternalIface('nsIControllers', nativeType='nsIControllers')
addExternalIface('nsIDOMCrypto', nativeType='nsIDOMCrypto',
headerFile='Crypto.h')
addExternalIface('nsIInputStreamCallback', nativeType='nsIInputStreamCallback',
headerFile='nsIAsyncInputStream.h')
+addExternalIface('nsIFile', nativeType='nsIFile', notflattened=True)
addExternalIface('nsIMessageBroadcaster', nativeType='nsIMessageBroadcaster',
headerFile='nsIMessageManager.h', notflattened=True)
addExternalIface('nsISelectionListener', nativeType='nsISelectionListener')
addExternalIface('nsIStreamListener', nativeType='nsIStreamListener', notflattened=True)
addExternalIface('nsISupports', nativeType='nsISupports')
addExternalIface('nsIDocShell', nativeType='nsIDocShell', notflattened=True)
addExternalIface('nsIEditor', nativeType='nsIEditor', notflattened=True)
addExternalIface('nsIVariant', nativeType='nsIVariant', notflattened=True)
--- a/dom/bluetooth/BluetoothAdapter.cpp
+++ b/dom/bluetooth/BluetoothAdapter.cpp
@@ -3,16 +3,17 @@
/* 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 "base/basictypes.h"
#include "nsDOMClassInfo.h"
#include "nsTArrayHelpers.h"
#include "DOMRequest.h"
+#include "nsDOMFile.h"
#include "nsThreadUtils.h"
#include "mozilla/dom/bluetooth/BluetoothTypes.h"
#include "mozilla/dom/BluetoothAdapterBinding.h"
#include "mozilla/dom/BluetoothDeviceEvent.h"
#include "mozilla/dom/BluetoothDiscoveryStateChangedEvent.h"
#include "mozilla/dom/BluetoothStatusChangedEvent.h"
#include "mozilla/dom/ContentChild.h"
@@ -765,17 +766,17 @@ BluetoothAdapter::IsConnected(const uint
}
bs->IsConnected(aServiceUuid, results);
return request.forget();
}
already_AddRefed<DOMRequest>
BluetoothAdapter::SendFile(const nsAString& aDeviceAddress,
- nsIDOMBlob* aBlob, ErrorResult& aRv)
+ DOMFile& aBlob, ErrorResult& aRv)
{
nsCOMPtr<nsPIDOMWindow> win = GetOwner();
if (!win) {
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
nsRefPtr<DOMRequest> request = new DOMRequest(win);
@@ -785,25 +786,25 @@ BluetoothAdapter::SendFile(const nsAStri
BluetoothService* bs = BluetoothService::Get();
if (!bs) {
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
if (XRE_GetProcessType() == GeckoProcessType_Default) {
// In-process transfer
- bs->SendFile(aDeviceAddress, aBlob, results);
+ bs->SendFile(aDeviceAddress, &aBlob, results);
} else {
ContentChild *cc = ContentChild::GetSingleton();
if (!cc) {
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
- BlobChild* actor = cc->GetOrCreateActorForBlob(aBlob);
+ BlobChild* actor = cc->GetOrCreateActorForBlob(&aBlob);
if (!actor) {
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
bs->SendFile(aDeviceAddress, nullptr, actor, results);
}
--- a/dom/bluetooth/BluetoothAdapter.h
+++ b/dom/bluetooth/BluetoothAdapter.h
@@ -10,16 +10,17 @@
#include "mozilla/Attributes.h"
#include "mozilla/DOMEventTargetHelper.h"
#include "BluetoothCommon.h"
#include "BluetoothPropertyContainer.h"
#include "nsCOMPtr.h"
namespace mozilla {
namespace dom {
+class DOMFile;
class DOMRequest;
struct MediaMetaData;
struct MediaPlayStatus;
}
}
BEGIN_BLUETOOTH_NAMESPACE
@@ -128,17 +129,17 @@ public:
already_AddRefed<DOMRequest>
IsConnected(const uint16_t aServiceUuid,
ErrorResult& aRv);
already_AddRefed<DOMRequest>
GetConnectedDevices(uint16_t aServiceUuid, ErrorResult& aRv);
already_AddRefed<DOMRequest>
- SendFile(const nsAString& aDeviceAddress, nsIDOMBlob* aBlob,
+ SendFile(const nsAString& aDeviceAddress, DOMFile& aBlob,
ErrorResult& aRv);
already_AddRefed<DOMRequest>
StopSendingFile(const nsAString& aDeviceAddress, ErrorResult& aRv);
already_AddRefed<DOMRequest>
ConfirmReceivingFile(const nsAString& aDeviceAddress, bool aConfirmation,
ErrorResult& aRv);
already_AddRefed<DOMRequest> ConnectSco(ErrorResult& aRv);
--- a/dom/bluetooth/bluedroid/BluetoothOppManager.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothOppManager.cpp
@@ -15,31 +15,32 @@
#include "mozilla/dom/bluetooth/BluetoothTypes.h"
#include "mozilla/dom/ipc/BlobParent.h"
#include "mozilla/RefPtr.h"
#include "mozilla/Services.h"
#include "mozilla/StaticPtr.h"
#include "nsAutoPtr.h"
#include "nsCExternalHandlerService.h"
+#include "nsDOMFile.h"
#include "nsIObserver.h"
#include "nsIObserverService.h"
-#include "nsIDOMFile.h"
#include "nsIFile.h"
#include "nsIInputStream.h"
#include "nsIMIMEService.h"
#include "nsIOutputStream.h"
#include "nsIVolumeService.h"
#include "nsNetUtil.h"
#include "nsServiceManagerUtils.h"
#define TARGET_SUBDIR "Download/Bluetooth/"
USING_BLUETOOTH_NAMESPACE
using namespace mozilla;
+using namespace mozilla::dom;
using namespace mozilla::ipc;
namespace {
// Sending system message "bluetooth-opp-update-progress" every 50kb
static const uint32_t kUpdateProgressBase = 50 * 1024;
/*
* The format of the header of an PUT request is
@@ -344,17 +345,18 @@ BluetoothOppManager::StartSendingNextFil
}
bool
BluetoothOppManager::SendFile(const nsAString& aDeviceAddress,
BlobParent* aActor)
{
MOZ_ASSERT(NS_IsMainThread());
- nsCOMPtr<nsIDOMBlob> blob = aActor->GetBlob();
+ nsRefPtr<DOMFileImpl> impl = aActor->GetBlobImpl();
+ nsCOMPtr<nsIDOMBlob> blob = new DOMFile(nullptr, impl);
return SendFile(aDeviceAddress, blob.get());
}
bool
BluetoothOppManager::SendFile(const nsAString& aDeviceAddress,
nsIDOMBlob* aBlob)
{
--- a/dom/bluetooth/bluez/BluetoothOppManager.cpp
+++ b/dom/bluetooth/bluez/BluetoothOppManager.cpp
@@ -15,31 +15,32 @@
#include "mozilla/dom/bluetooth/BluetoothTypes.h"
#include "mozilla/dom/ipc/BlobParent.h"
#include "mozilla/RefPtr.h"
#include "mozilla/Services.h"
#include "mozilla/StaticPtr.h"
#include "nsAutoPtr.h"
#include "nsCExternalHandlerService.h"
+#include "nsDOMFile.h"
#include "nsIObserver.h"
#include "nsIObserverService.h"
-#include "nsIDOMFile.h"
#include "nsIFile.h"
#include "nsIInputStream.h"
#include "nsIMIMEService.h"
#include "nsIOutputStream.h"
#include "nsIVolumeService.h"
#include "nsNetUtil.h"
#include "nsServiceManagerUtils.h"
#define TARGET_SUBDIR "Download/Bluetooth/"
USING_BLUETOOTH_NAMESPACE
using namespace mozilla;
+using namespace mozilla::dom;
using namespace mozilla::ipc;
using mozilla::TimeDuration;
using mozilla::TimeStamp;
namespace {
// Sending system message "bluetooth-opp-update-progress" every 50kb
static const uint32_t kUpdateProgressBase = 50 * 1024;
@@ -366,17 +367,18 @@ BluetoothOppManager::StartSendingNextFil
}
bool
BluetoothOppManager::SendFile(const nsAString& aDeviceAddress,
BlobParent* aActor)
{
MOZ_ASSERT(NS_IsMainThread());
- nsCOMPtr<nsIDOMBlob> blob = aActor->GetBlob();
+ nsRefPtr<DOMFileImpl> impl = aActor->GetBlobImpl();
+ nsCOMPtr<nsIDOMBlob> blob = new DOMFile(nullptr, impl);
return SendFile(aDeviceAddress, blob.get());
}
bool
BluetoothOppManager::SendFile(const nsAString& aDeviceAddress,
nsIDOMBlob* aBlob)
{
--- a/dom/browser-element/BrowserElementParent.jsm
+++ b/dom/browser-element/BrowserElementParent.jsm
@@ -575,17 +575,18 @@ BrowserElementParent.prototype = {
if ('successRv' in data.json) {
debug("Successful gotDOMRequestResult.");
let clientObj = Cu.cloneInto(data.json.successRv, this._window);
Services.DOMRequest.fireSuccess(req, clientObj);
}
else {
debug("Got error in gotDOMRequestResult.");
- Services.DOMRequest.fireErrorAsync(req, data.json.errorMsg);
+ Services.DOMRequest.fireErrorAsync(req,
+ Cu.cloneInto(data.json.errorMsg, this._window));
}
},
_setVisible: function(visible) {
this._sendAsyncMsg('set-visible', {visible: visible});
this._frameLoader.visible = visible;
},
--- a/dom/camera/DOMCameraControl.cpp
+++ b/dom/camera/DOMCameraControl.cpp
@@ -1432,33 +1432,35 @@ nsDOMCameraControl::OnFacesDetected(cons
DispatchTrustedEvent(event);
}
void
nsDOMCameraControl::OnTakePictureComplete(nsIDOMBlob* aPicture)
{
MOZ_ASSERT(NS_IsMainThread());
- MOZ_ASSERT(aPicture != nullptr);
+ MOZ_ASSERT(aPicture);
nsRefPtr<Promise> promise = mTakePicturePromise.forget();
if (promise) {
nsCOMPtr<nsIDOMBlob> picture = aPicture;
promise->MaybeResolve(picture);
}
+ nsRefPtr<DOMFile> blob = static_cast<DOMFile*>(aPicture);
+
nsRefPtr<CameraTakePictureCallback> cb = mTakePictureOnSuccessCb.forget();
mTakePictureOnErrorCb = nullptr;
if (cb) {
ErrorResult ignored;
- cb->Call(aPicture, ignored);
+ cb->Call(*blob, ignored);
}
BlobEventInit eventInit;
- eventInit.mData = aPicture;
+ eventInit.mData = blob;
nsRefPtr<BlobEvent> event = BlobEvent::Constructor(this,
NS_LITERAL_STRING("picture"),
eventInit);
DispatchTrustedEvent(event);
}
--- a/dom/camera/DOMCameraControlListener.cpp
+++ b/dom/camera/DOMCameraControlListener.cpp
@@ -343,17 +343,18 @@ DOMCameraControlListener::OnTakePictureC
, mLength(aLength)
, mMimeType(aMimeType)
{ }
void
RunCallback(nsDOMCameraControl* aDOMCameraControl) MOZ_OVERRIDE
{
nsCOMPtr<nsIDOMBlob> picture =
- DOMFile::CreateMemoryFile(static_cast<void*>(mData),
+ DOMFile::CreateMemoryFile(mDOMCameraControl,
+ static_cast<void*>(mData),
static_cast<uint64_t>(mLength),
mMimeType);
aDOMCameraControl->OnTakePictureComplete(picture);
}
protected:
uint8_t* mData;
uint32_t mLength;
--- a/dom/contacts/ContactManager.js
+++ b/dom/contacts/ContactManager.js
@@ -85,18 +85,19 @@ ContactManager.prototype = {
this.__DOM_IMPL__.setEventHandler("oncontactchange", aHandler);
},
get oncontactchange() {
return this.__DOM_IMPL__.getEventHandler("oncontactchange");
},
_convertContact: function(aContact) {
- let newContact = new this._window.mozContact(aContact.properties);
- newContact.setMetadata(aContact.id, aContact.published, aContact.updated);
+ let contact = Cu.cloneInto(aContact, this._window);
+ let newContact = new this._window.mozContact(contact.properties);
+ newContact.setMetadata(contact.id, contact.published, contact.updated);
return newContact;
},
_convertContacts: function(aContacts) {
let contacts = new this._window.Array();
for (let i in aContacts) {
contacts.push(this._convertContact(aContacts[i]));
}
--- a/dom/contacts/tests/test_contacts_blobs.html
+++ b/dom/contacts/tests/test_contacts_blobs.html
@@ -83,24 +83,24 @@ var properties2 = {
};
var sample_id1;
var createResult1;
var findResult1;
function verifyBlob(blob1, blob2, isLast)
{
- is(blob1 instanceof SpecialPowers.Ci.nsIDOMBlob, true,
- "blob1 is an instance of nsIDOMBlob");
- is(blob2 instanceof SpecialPowers.Ci.nsIDOMBlob, true,
- "blob2 is an instance of nsIDOMBlob");
- isnot(blob1 instanceof SpecialPowers.Ci.nsIDOMFile, true,
- "blob1 is an instance of nsIDOMFile");
- isnot(blob2 instanceof SpecialPowers.Ci.nsIDOMFile, true,
- "blob2 is an instance of nsIDOMFile");
+ is(blob1 instanceof Blob, true,
+ "blob1 is an instance of DOMBlob");
+ is(blob2 instanceof Blob, true,
+ "blob2 is an instance of DOMBlob");
+ isnot(blob1 instanceof File, true,
+ "blob1 is an instance of DOMFile");
+ isnot(blob2 instanceof File, true,
+ "blob2 is an instance of DOMFile");
ise(blob1.size, blob2.size, "Same size");
ise(blob1.type, blob2.type, "Same type");
var buffer1;
var buffer2;
var reader1 = new FileReader();
reader1.readAsArrayBuffer(blob2);
--- a/dom/devicestorage/DeviceStorageRequestChild.cpp
+++ b/dom/devicestorage/DeviceStorageRequestChild.cpp
@@ -98,22 +98,25 @@ DeviceStorageRequestChild::
mRequest->FireSuccess(result);
break;
}
case DeviceStorageResponseValue::TBlobResponse:
{
BlobResponse r = aValue;
BlobChild* actor = static_cast<BlobChild*>(r.blobChild());
- nsCOMPtr<nsIDOMBlob> blob = actor->GetBlob();
+ nsRefPtr<DOMFileImpl> bloblImpl = actor->GetBlobImpl();
+ nsRefPtr<DOMFile> blob = new DOMFile(mRequest->GetParentObject(), bloblImpl);
+
+ AutoJSContext cx;
- nsCOMPtr<nsIDOMFile> file = do_QueryInterface(blob);
- AutoJSContext cx;
- JS::Rooted<JS::Value> result(cx,
- InterfaceToJsval(window, file, &NS_GET_IID(nsIDOMFile)));
+ JS::Rooted<JSObject*> obj(cx, blob->WrapObject(cx));
+ MOZ_ASSERT(obj);
+
+ JS::Rooted<JS::Value> result(cx, JS::ObjectValue(*obj));
mRequest->FireSuccess(result);
break;
}
case DeviceStorageResponseValue::TFreeSpaceStorageResponse:
{
FreeSpaceStorageResponse r = aValue;
AutoJSContext cx;
--- a/dom/devicestorage/DeviceStorageRequestParent.cpp
+++ b/dom/devicestorage/DeviceStorageRequestParent.cpp
@@ -39,20 +39,20 @@ DeviceStorageRequestParent::Dispatch()
case DeviceStorageParams::TDeviceStorageAddParams:
{
DeviceStorageAddParams p = mParams;
nsRefPtr<DeviceStorageFile> dsf =
new DeviceStorageFile(p.type(), p.storageName(), p.relpath());
BlobParent* bp = static_cast<BlobParent*>(p.blobParent());
- nsCOMPtr<nsIDOMBlob> blob = bp->GetBlob();
+ nsRefPtr<DOMFileImpl> blobImpl = bp->GetBlobImpl();
nsCOMPtr<nsIInputStream> stream;
- blob->GetInternalStream(getter_AddRefs(stream));
+ blobImpl->GetInternalStream(getter_AddRefs(stream));
nsRefPtr<CancelableRunnable> r = new WriteFileEvent(this, dsf, stream,
DEVICE_STORAGE_REQUEST_CREATE);
nsCOMPtr<nsIEventTarget> target
= do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
MOZ_ASSERT(target);
target->Dispatch(r, NS_DISPATCH_NORMAL);
@@ -62,20 +62,20 @@ DeviceStorageRequestParent::Dispatch()
case DeviceStorageParams::TDeviceStorageAppendParams:
{
DeviceStorageAppendParams p = mParams;
nsRefPtr<DeviceStorageFile> dsf =
new DeviceStorageFile(p.type(), p.storageName(), p.relpath());
BlobParent* bp = static_cast<BlobParent*>(p.blobParent());
- nsCOMPtr<nsIDOMBlob> blob = bp->GetBlob();
+ nsRefPtr<DOMFileImpl> blobImpl = bp->GetBlobImpl();
nsCOMPtr<nsIInputStream> stream;
- blob->GetInternalStream(getter_AddRefs(stream));
+ blobImpl->GetInternalStream(getter_AddRefs(stream));
nsRefPtr<CancelableRunnable> r = new WriteFileEvent(this, dsf, stream,
DEVICE_STORAGE_REQUEST_APPEND);
nsCOMPtr<nsIEventTarget> target
= do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
MOZ_ASSERT(target);
target->Dispatch(r, NS_DISPATCH_NORMAL);
@@ -517,17 +517,17 @@ nsresult
DeviceStorageRequestParent::PostBlobSuccessEvent::CancelableRun() {
MOZ_ASSERT(NS_IsMainThread());
nsString mime;
CopyASCIItoUTF16(mMimeType, mime);
nsString fullPath;
mFile->GetFullPath(fullPath);
- nsCOMPtr<nsIDOMBlob> blob = new DOMFile(
+ nsRefPtr<DOMFile> blob = new DOMFile(nullptr,
new DOMFileImplFile(fullPath, mime, mLength, mFile->mFile,
mLastModificationDate));
ContentParent* cp = static_cast<ContentParent*>(mParent->Manager());
BlobParent* actor = cp->GetOrCreateActorForBlob(blob);
if (!actor) {
ErrorResponse response(NS_LITERAL_STRING(POST_ERROR_EVENT_UNKNOWN));
unused << mParent->Send__delete__(mParent, response);
--- a/dom/devicestorage/nsDeviceStorage.cpp
+++ b/dom/devicestorage/nsDeviceStorage.cpp
@@ -1800,17 +1800,17 @@ nsIFileToJsval(nsPIDOMWindow* aWindow, D
aFile->GetFullPath(fullPath);
// This check is useful to know if somewhere the DeviceStorageFile
// has not been properly set. Mimetype is not checked because it can be
// empty.
MOZ_ASSERT(aFile->mLength != UINT64_MAX);
MOZ_ASSERT(aFile->mLastModifiedDate != UINT64_MAX);
- nsCOMPtr<nsIDOMBlob> blob = new DOMFile(
+ nsCOMPtr<nsIDOMBlob> blob = new DOMFile(aWindow,
new DOMFileImplFile(fullPath, aFile->mMimeType,
aFile->mLength, aFile->mFile,
aFile->mLastModifiedDate));
return InterfaceToJsval(aWindow, blob, &NS_GET_IID(nsIDOMBlob));
}
bool
StringToJsval(nsPIDOMWindow* aWindow, nsAString& aString,
@@ -2909,17 +2909,18 @@ public:
!typeChecker->Check(mFile->mStorageType, mBlob)) {
r = new PostErrorEvent(mRequest.forget(),
POST_ERROR_EVENT_ILLEGAL_TYPE);
return NS_DispatchToCurrentThread(r);
}
if (XRE_GetProcessType() != GeckoProcessType_Default) {
BlobChild* actor
- = ContentChild::GetSingleton()->GetOrCreateActorForBlob(mBlob);
+ = ContentChild::GetSingleton()->GetOrCreateActorForBlob(
+ static_cast<DOMFile*>(mBlob.get()));
if (!actor) {
return NS_ERROR_FAILURE;
}
DeviceStorageAddParams params;
params.blobChild() = actor;
params.type() = mFile->mStorageType;
params.storageName() = mFile->mStorageName;
@@ -2954,17 +2955,18 @@ public:
!typeChecker->Check(mFile->mStorageType, mBlob)) {
r = new PostErrorEvent(mRequest.forget(),
POST_ERROR_EVENT_ILLEGAL_TYPE);
return NS_DispatchToCurrentThread(r);
}
if (XRE_GetProcessType() != GeckoProcessType_Default) {
BlobChild* actor
- = ContentChild::GetSingleton()->GetOrCreateActorForBlob(mBlob);
+ = ContentChild::GetSingleton()->GetOrCreateActorForBlob(
+ static_cast<DOMFile*>(mBlob.get()));
if (!actor) {
return NS_ERROR_FAILURE;
}
DeviceStorageAppendParams params;
params.blobChild() = actor;
params.type() = mFile->mStorageType;
params.storageName() = mFile->mStorageName;
--- a/dom/events/DataTransfer.cpp
+++ b/dom/events/DataTransfer.cpp
@@ -298,17 +298,18 @@ DataTransfer::GetFiles(ErrorResult& aRv)
if (NS_FAILED(rv))
continue;
nsCOMPtr<nsIFile> file = do_QueryInterface(supports);
if (!file)
continue;
- nsRefPtr<DOMFile> domFile = DOMFile::CreateFromFile(file);
+ nsRefPtr<DOMFile> domFile =
+ DOMFile::CreateFromFile(GetParentObject(), file);
if (!mFiles->Append(domFile)) {
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
}
}
--- a/dom/events/test/test_eventctors.html
+++ b/dom/events/test/test_eventctors.html
@@ -198,17 +198,17 @@ ok(ex, "Shouldn't be able to re-define t
ex = false;
ok(!e.isTrusted, "BlobEvent shouldn't be trusted!");
ok(!e.bubbles, "Event shouldn't bubble!");
ok(!e.cancelable, "Event shouldn't be cancelable!");
document.dispatchEvent(e);
is(receivedEvent, e, "Wrong event!");
-var blob = Blob();
+var blob = new Blob();
e = new BlobEvent("hello", { bubbles: true, cancelable: true, data: blob });
is(e.type, "hello", "Wrong event type!");
ok(!e.isTrusted, "Event shouldn't be trusted!");
ok(e.bubbles, "Event should bubble!");
ok(e.cancelable, "Event should be cancelable!");
is(e.data, blob , "Wrong event.data!");
document.dispatchEvent(e);
is(receivedEvent, e, "Wrong event!");
--- a/dom/filehandle/FileHandle.cpp
+++ b/dom/filehandle/FileHandle.cpp
@@ -12,17 +12,17 @@
#include "FileService.h"
#include "FileStreamWrappers.h"
#include "MemoryStreams.h"
#include "mozilla/dom/EncodingUtils.h"
#include "MutableFile.h"
#include "nsContentUtils.h"
#include "nsDebug.h"
#include "nsError.h"
-#include "nsIDOMFile.h"
+#include "nsDOMFile.h"
#include "nsIEventTarget.h"
#include "nsISeekableStream.h"
#include "nsNetUtil.h"
#include "nsString.h"
#include "nsStringStream.h"
#include "nsThreadUtils.h"
#include "xpcpublic.h"
@@ -617,27 +617,27 @@ FileHandleBase::GetInputStream(const Arr
}
*aInputLength = length;
return stream.forget();
}
// static
already_AddRefed<nsIInputStream>
-FileHandleBase::GetInputStream(nsIDOMBlob* aValue, uint64_t* aInputLength,
+FileHandleBase::GetInputStream(const DOMFile& aValue, uint64_t* aInputLength,
ErrorResult& aRv)
{
- uint64_t length;
- aRv = aValue->GetSize(&length);
+ DOMFile& file = const_cast<DOMFile&>(aValue);
+ uint64_t length = file.GetSize(aRv);
if (aRv.Failed()) {
return nullptr;
}
nsCOMPtr<nsIInputStream> stream;
- aRv = aValue->GetInternalStream(getter_AddRefs(stream));
+ aRv = file.GetInternalStream(getter_AddRefs(stream));
if (aRv.Failed()) {
return nullptr;
}
*aInputLength = length;
return stream.forget();
}
--- a/dom/filehandle/FileHandle.h
+++ b/dom/filehandle/FileHandle.h
@@ -16,21 +16,21 @@
#include "mozilla/ErrorResult.h"
#include "nsAutoPtr.h"
#include "nsCOMPtr.h"
#include "nsIInputStream.h"
#include "nsIRunnable.h"
#include "nsTArray.h"
class nsAString;
-class nsIDOMBlob;
namespace mozilla {
namespace dom {
+class DOMFile;
class FileHelper;
class FileRequestBase;
class FileService;
class FinishHelper;
class MetadataHelper;
class MutableFileBase;
/**
@@ -235,17 +235,18 @@ protected:
nsresult
Finish();
static already_AddRefed<nsIInputStream>
GetInputStream(const ArrayBuffer& aValue, uint64_t* aInputLength,
ErrorResult& aRv);
static already_AddRefed<nsIInputStream>
- GetInputStream(nsIDOMBlob* aValue, uint64_t* aInputLength, ErrorResult& aRv);
+ GetInputStream(const DOMFile& aValue, uint64_t* aInputLength,
+ ErrorResult& aRv);
static already_AddRefed<nsIInputStream>
GetInputStream(const nsAString& aValue, uint64_t* aInputLength,
ErrorResult& aRv);
};
class FinishHelper MOZ_FINAL : public nsIRunnable
{
--- a/dom/filesystem/CreateFileTask.cpp
+++ b/dom/filesystem/CreateFileTask.cpp
@@ -22,17 +22,17 @@
namespace mozilla {
namespace dom {
uint32_t CreateFileTask::sOutputBufferSize = 0;
CreateFileTask::CreateFileTask(FileSystemBase* aFileSystem,
const nsAString& aPath,
- nsIDOMBlob* aBlobData,
+ DOMFile* aBlobData,
InfallibleTArray<uint8_t>& aArrayData,
bool replace,
ErrorResult& aRv)
: FileSystemTaskBase(aFileSystem)
, mTargetRealPath(aPath)
, mReplace(replace)
{
MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
@@ -74,19 +74,20 @@ CreateFileTask::CreateFileTask(FileSyste
auto& data = aParam.data();
if (data.type() == FileSystemFileDataValue::TArrayOfuint8_t) {
mArrayData = data;
return;
}
BlobParent* bp = static_cast<BlobParent*>(static_cast<PBlobParent*>(data));
- nsCOMPtr<nsIDOMBlob> blobData = bp->GetBlob();
- MOZ_ASSERT(blobData, "blobData should not be null.");
- nsresult rv = blobData->GetInternalStream(getter_AddRefs(mBlobStream));
+ nsRefPtr<DOMFileImpl> blobImpl = bp->GetBlobImpl();
+ MOZ_ASSERT(blobImpl, "blobData should not be null.");
+
+ nsresult rv = blobImpl->GetInternalStream(getter_AddRefs(mBlobStream));
NS_WARN_IF(NS_FAILED(rv));
}
CreateFileTask::~CreateFileTask()
{
MOZ_ASSERT((!mPromise && !mBlobData) || NS_IsMainThread(),
"mPromise and mBlobData should be released on main thread!");
@@ -121,34 +122,34 @@ CreateFileTask::GetRequestParams(const n
}
return param;
}
FileSystemResponseValue
CreateFileTask::GetSuccessRequestResult() const
{
MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
- nsRefPtr<DOMFile> file = new DOMFile(mTargetFileImpl);
+ nsRefPtr<DOMFile> file = new DOMFile(mFileSystem->GetWindow(),
+ mTargetFileImpl);
BlobParent* actor = GetBlobParent(file);
if (!actor) {
return FileSystemErrorResponse(NS_ERROR_DOM_FILESYSTEM_UNKNOWN_ERR);
}
FileSystemFileResponse response;
response.blobParent() = actor;
return response;
}
void
CreateFileTask::SetSuccessRequestResult(const FileSystemResponseValue& aValue)
{
MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
FileSystemFileResponse r = aValue;
BlobChild* actor = static_cast<BlobChild*>(r.blobChild());
- nsCOMPtr<nsIDOMBlob> blob = actor->GetBlob();
- mTargetFileImpl = static_cast<DOMFile*>(blob.get())->Impl();
+ mTargetFileImpl = actor->GetBlobImpl();
}
nsresult
CreateFileTask::Work()
{
class AutoClose
{
public:
@@ -297,17 +298,18 @@ CreateFileTask::HandlerCallback()
nsRefPtr<DOMError> domError = new DOMError(mFileSystem->GetWindow(),
mErrorValue);
mPromise->MaybeRejectBrokenly(domError);
mPromise = nullptr;
mBlobData = nullptr;
return;
}
- nsCOMPtr<nsIDOMFile> file = new DOMFile(mTargetFileImpl);
+ nsCOMPtr<nsIDOMFile> file = new DOMFile(mFileSystem->GetWindow(),
+ mTargetFileImpl);
mPromise->MaybeResolve(file);
mPromise = nullptr;
mBlobData = nullptr;
}
void
CreateFileTask::GetPermissionAccessType(nsCString& aAccess) const
{
--- a/dom/filesystem/CreateFileTask.h
+++ b/dom/filesystem/CreateFileTask.h
@@ -6,32 +6,32 @@
#ifndef mozilla_dom_CreateFileTask_h
#define mozilla_dom_CreateFileTask_h
#include "mozilla/dom/FileSystemTaskBase.h"
#include "nsAutoPtr.h"
#include "mozilla/ErrorResult.h"
-class nsIDOMBlob;
class nsIInputStream;
namespace mozilla {
namespace dom {
+class DOMFile;
class DOMFileImpl;
class Promise;
class CreateFileTask MOZ_FINAL
: public FileSystemTaskBase
{
public:
CreateFileTask(FileSystemBase* aFileSystem,
const nsAString& aPath,
- nsIDOMBlob* aBlobData,
+ DOMFile* aBlobData,
InfallibleTArray<uint8_t>& aArrayData,
bool replace,
ErrorResult& aRv);
CreateFileTask(FileSystemBase* aFileSystem,
const FileSystemCreateFileParams& aParam,
FileSystemRequestParent* aParent);
virtual
@@ -63,17 +63,17 @@ private:
void
GetOutputBufferSize() const;
static uint32_t sOutputBufferSize;
nsRefPtr<Promise> mPromise;
nsString mTargetRealPath;
// Not thread-safe and should be released on main thread.
- nsCOMPtr<nsIDOMBlob> mBlobData;
+ nsRefPtr<DOMFile> mBlobData;
nsCOMPtr<nsIInputStream> mBlobStream;
InfallibleTArray<uint8_t> mArrayData;
bool mReplace;
// This cannot be a DOMFile because this object is created on a different
// thread and DOMFile is not thread-safe. Let's use the DOMFileImpl instead.
nsRefPtr<DOMFileImpl> mTargetFileImpl;
--- a/dom/filesystem/DeviceStorageFileSystem.cpp
+++ b/dom/filesystem/DeviceStorageFileSystem.cpp
@@ -118,17 +118,19 @@ DeviceStorageFileSystem::GetRealPath(DOM
{
MOZ_ASSERT(FileSystemUtils::IsParentProcess(),
"Should be on parent process!");
MOZ_ASSERT(aFile, "aFile Should not be null.");
aRealPath.Truncate();
nsAutoString filePath;
- if (NS_FAILED(aFile->GetMozFullPathInternal(filePath))) {
+ ErrorResult rv;
+ aFile->GetMozFullPathInternal(filePath, rv);
+ if (NS_WARN_IF(rv.Failed())) {
return false;
}
return LocalPathToRealPath(filePath, aRealPath);
}
const nsAString&
DeviceStorageFileSystem::GetRootName() const
--- a/dom/filesystem/Directory.cpp
+++ b/dom/filesystem/Directory.cpp
@@ -96,17 +96,17 @@ Directory::GetName(nsString& aRetval) co
}
already_AddRefed<Promise>
Directory::CreateFile(const nsAString& aPath, const CreateFileOptions& aOptions,
ErrorResult& aRv)
{
nsresult error = NS_OK;
nsString realPath;
- nsRefPtr<nsIDOMBlob> blobData;
+ nsRefPtr<DOMFile> blobData;
InfallibleTArray<uint8_t> arrayData;
bool replace = (aOptions.mIfExists == CreateIfExistsMode::Replace);
// Get the file content.
if (aOptions.mData.WasPassed()) {
auto& data = aOptions.mData.Value();
if (data.IsString()) {
NS_ConvertUTF16toUTF8 str(data.GetAsString());
@@ -124,18 +124,18 @@ Directory::CreateFile(const nsAString& a
blobData = data.GetAsBlob();
}
}
if (!DOMPathToRealPath(aPath, realPath)) {
error = NS_ERROR_DOM_FILESYSTEM_INVALID_PATH_ERR;
}
- nsRefPtr<CreateFileTask> task = new CreateFileTask(mFileSystem, realPath,
- blobData, arrayData, replace, aRv);
+ nsRefPtr<CreateFileTask> task =
+ new CreateFileTask(mFileSystem, realPath, blobData, arrayData, replace, aRv);
if (aRv.Failed()) {
return nullptr;
}
task->SetError(error);
FileSystemPermissionRequest::RequestForTask(task);
return task->GetPromise();
}
@@ -193,17 +193,17 @@ Directory::RemoveInternal(const StringOr
{
nsresult error = NS_OK;
nsString realPath;
nsRefPtr<DOMFileImpl> file;
// Check and get the target path.
if (aPath.IsFile()) {
- file = static_cast<DOMFile*>(aPath.GetAsFile())->Impl();
+ file = aPath.GetAsFile().Impl();
goto parameters_check_done;
}
if (aPath.IsString()) {
if (!DOMPathToRealPath(aPath.GetAsString(), realPath)) {
error = NS_ERROR_DOM_FILESYSTEM_INVALID_PATH_ERR;
}
goto parameters_check_done;
--- a/dom/filesystem/FileSystemTaskBase.cpp
+++ b/dom/filesystem/FileSystemTaskBase.cpp
@@ -165,17 +165,17 @@ FileSystemTaskBase::GetBlobParent(nsIDOM
nsString mimeType;
aFile->GetType(mimeType);
uint64_t fileSize;
aFile->GetSize(&fileSize);
uint64_t lastModifiedDate;
aFile->GetMozLastModifiedDate(&lastModifiedDate);
ContentParent* cp = static_cast<ContentParent*>(mRequestParent->Manager());
- return cp->GetOrCreateActorForBlob(aFile);
+ return cp->GetOrCreateActorForBlob(static_cast<DOMFile*>(aFile));
}
void
FileSystemTaskBase::SetError(const nsresult& aErrorValue)
{
uint16_t module = NS_ERROR_GET_MODULE(aErrorValue);
if (module == NS_ERROR_MODULE_DOM_FILESYSTEM ||
module == NS_ERROR_MODULE_DOM_FILE ||
--- a/dom/filesystem/GetFileOrDirectoryTask.cpp
+++ b/dom/filesystem/GetFileOrDirectoryTask.cpp
@@ -3,16 +3,17 @@
/* 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 "GetFileOrDirectoryTask.h"
#include "js/Value.h"
#include "mozilla/dom/Directory.h"
+#include "mozilla/dom/DOMError.h"
#include "mozilla/dom/FileSystemBase.h"
#include "mozilla/dom/FileSystemUtils.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/ipc/BlobChild.h"
#include "mozilla/dom/ipc/BlobParent.h"
#include "nsDOMFile.h"
#include "nsIFile.h"
#include "nsStringGlue.h"
@@ -76,17 +77,18 @@ GetFileOrDirectoryTask::GetRequestParams
FileSystemResponseValue
GetFileOrDirectoryTask::GetSuccessRequestResult() const
{
MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
if (mIsDirectory) {
return FileSystemDirectoryResponse(mTargetRealPath);
}
- nsRefPtr<DOMFile> file = new DOMFile(mTargetFileImpl);
+ nsRefPtr<DOMFile> file = new DOMFile(mFileSystem->GetWindow(),
+ mTargetFileImpl);
BlobParent* actor = GetBlobParent(file);
if (!actor) {
return FileSystemErrorResponse(NS_ERROR_DOM_FILESYSTEM_UNKNOWN_ERR);
}
FileSystemFileResponse response;
response.blobParent() = actor;
return response;
}
@@ -94,18 +96,17 @@ GetFileOrDirectoryTask::GetSuccessReques
void
GetFileOrDirectoryTask::SetSuccessRequestResult(const FileSystemResponseValue& aValue)
{
MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
switch (aValue.type()) {
case FileSystemResponseValue::TFileSystemFileResponse: {
FileSystemFileResponse r = aValue;
BlobChild* actor = static_cast<BlobChild*>(r.blobChild());
- nsCOMPtr<nsIDOMBlob> blob = actor->GetBlob();
- mTargetFileImpl = static_cast<DOMFile*>(blob.get())->Impl();
+ mTargetFileImpl = actor->GetBlobImpl();
mIsDirectory = false;
break;
}
case FileSystemResponseValue::TFileSystemDirectoryResponse: {
FileSystemDirectoryResponse r = aValue;
mTargetRealPath = r.realPath();
mIsDirectory = true;
break;
@@ -209,17 +210,18 @@ GetFileOrDirectoryTask::HandlerCallback(
if (mIsDirectory) {
nsRefPtr<Directory> dir = new Directory(mFileSystem, mTargetRealPath);
mPromise->MaybeResolve(dir);
mPromise = nullptr;
return;
}
- nsCOMPtr<nsIDOMFile> file = new DOMFile(mTargetFileImpl);
+ nsCOMPtr<nsIDOMFile> file = new DOMFile(mFileSystem->GetWindow(),
+ mTargetFileImpl);
mPromise->MaybeResolve(file);
mPromise = nullptr;
}
void
GetFileOrDirectoryTask::GetPermissionAccessType(nsCString& aAccess) const
{
aAccess.AssignLiteral("read");
--- a/dom/filesystem/RemoveTask.cpp
+++ b/dom/filesystem/RemoveTask.cpp
@@ -61,19 +61,18 @@ RemoveTask::RemoveTask(FileSystemBase* a
const FileSystemPathOrFileValue& target = aParam.target();
if (target.type() == FileSystemPathOrFileValue::TnsString) {
mTargetRealPath = target;
return;
}
BlobParent* bp = static_cast<BlobParent*>(static_cast<PBlobParent*>(target));
- nsCOMPtr<nsIDOMBlob> blob = bp->GetBlob();
- MOZ_ASSERT(blob);
- mTargetFileImpl = static_cast<DOMFile*>(blob.get())->Impl();
+ mTargetFileImpl = bp->GetBlobImpl();
+ MOZ_ASSERT(mTargetFileImpl);
}
RemoveTask::~RemoveTask()
{
MOZ_ASSERT(!mPromise || NS_IsMainThread(),
"mPromise should be released on main thread!");
}
@@ -88,17 +87,18 @@ FileSystemParams
RemoveTask::GetRequestParams(const nsString& aFileSystem) const
{
MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
FileSystemRemoveParams param;
param.filesystem() = aFileSystem;
param.directory() = mDirRealPath;
param.recursive() = mRecursive;
if (mTargetFileImpl) {
- nsRefPtr<DOMFile> file = new DOMFile(mTargetFileImpl);
+ nsRefPtr<DOMFile> file = new DOMFile(mFileSystem->GetWindow(),
+ mTargetFileImpl);
BlobChild* actor
= ContentChild::GetSingleton()->GetOrCreateActorForBlob(file);
if (actor) {
param.target() = actor;
}
} else {
param.target() = mTargetRealPath;
}
--- a/dom/indexedDB/ActorsChild.cpp
+++ b/dom/indexedDB/ActorsChild.cpp
@@ -519,18 +519,20 @@ ConvertActorsToBlobs(IDBDatabase* aDatab
if (!blobs.IsEmpty()) {
const uint32_t count = blobs.Length();
aFiles.SetCapacity(count);
for (uint32_t index = 0; index < count; index++) {
BlobChild* actor = static_cast<BlobChild*>(blobs[index]);
- nsCOMPtr<nsIDOMBlob> blob = actor->GetBlob();
- MOZ_ASSERT(blob);
+ nsRefPtr<DOMFileImpl> blobImpl = actor->GetBlobImpl();
+ MOZ_ASSERT(blobImpl);
+
+ nsRefPtr<DOMFile> blob = new DOMFile(aDatabase->GetOwner(), blobImpl);
nsRefPtr<FileInfo> fileInfo;
if (!fileInfos.IsEmpty()) {
fileInfo = dont_AddRef(reinterpret_cast<FileInfo*>(fileInfos[index]));
MOZ_ASSERT(fileInfo);
MOZ_ASSERT(fileInfo->Id() > 0);
--- a/dom/indexedDB/FileSnapshot.cpp
+++ b/dom/indexedDB/FileSnapshot.cpp
@@ -126,33 +126,35 @@ FileImplSnapshot::GetInternalStream(nsII
}
return NS_OK;
}
already_AddRefed<DOMFileImpl>
FileImplSnapshot::CreateSlice(uint64_t aStart,
uint64_t aLength,
- const nsAString& aContentType)
+ const nsAString& aContentType,
+ ErrorResult& aRv)
{
AssertSanity();
nsRefPtr<DOMFileImpl> impl =
new FileImplSnapshot(this, aStart, aLength, aContentType);
return impl.forget();
}
-nsresult
-FileImplSnapshot::GetMozFullPathInternal(nsAString& aFilename)
+void
+FileImplSnapshot::GetMozFullPathInternal(nsAString& aFilename,
+ ErrorResult& aRv)
{
AssertSanity();
MOZ_ASSERT(mIsFile);
- return mFile->GetPath(aFilename);
+ aRv = mFile->GetPath(aFilename);
}
bool
FileImplSnapshot::IsStoredFile() const
{
AssertSanity();
return true;
--- a/dom/indexedDB/FileSnapshot.h
+++ b/dom/indexedDB/FileSnapshot.h
@@ -54,35 +54,36 @@ private:
static void
AssertSanity()
#ifdef DEBUG
;
#else
{ }
#endif
- virtual nsresult
- GetMozFullPathInternal(nsAString& aFullPath) MOZ_OVERRIDE;
+ virtual void
+ GetMozFullPathInternal(nsAString& aFullPath, ErrorResult& aRv) MOZ_OVERRIDE;
virtual nsresult
GetInternalStream(nsIInputStream** aStream) MOZ_OVERRIDE;
virtual void
Unlink() MOZ_OVERRIDE;
virtual void
Traverse(nsCycleCollectionTraversalCallback &aCb) MOZ_OVERRIDE;
virtual bool
IsCCed() const MOZ_OVERRIDE;
virtual already_AddRefed<DOMFileImpl>
CreateSlice(uint64_t aStart,
uint64_t aLength,
- const nsAString& aContentType) MOZ_OVERRIDE;
+ const nsAString& aContentType,
+ ErrorResult& aRv) MOZ_OVERRIDE;
virtual bool
IsStoredFile() const MOZ_OVERRIDE;
virtual bool
IsWholeFile() const MOZ_OVERRIDE;
virtual bool
--- a/dom/indexedDB/IDBDatabase.cpp
+++ b/dom/indexedDB/IDBDatabase.cpp
@@ -798,33 +798,34 @@ IDBDatabase::AbortTransactions()
return PL_DHASH_NEXT;
}
};
Helper::AbortTransactions(mTransactions);
}
PBackgroundIDBDatabaseFileChild*
-IDBDatabase::GetOrCreateFileActorForBlob(nsIDOMBlob* aBlob)
+IDBDatabase::GetOrCreateFileActorForBlob(DOMFile* aBlob)
{
AssertIsOnOwningThread();
MOZ_ASSERT(aBlob);
MOZ_ASSERT(mBackgroundActor);
// We use the DOMFile's nsIWeakReference as the key to the table because
// a) it is unique per blob, b) it is reference-counted so that we can
// guarantee that it stays alive, and c) it doesn't hold the actual DOMFile
// alive.
- nsCOMPtr<nsIWeakReference> weakRef = do_GetWeakReference(aBlob);
+ nsCOMPtr<nsIDOMBlob> blob = aBlob;
+ nsCOMPtr<nsIWeakReference> weakRef = do_GetWeakReference(blob);
MOZ_ASSERT(weakRef);
PBackgroundIDBDatabaseFileChild* actor = nullptr;
if (!mFileActors.Get(weakRef, &actor)) {
- DOMFileImpl* blobImpl = static_cast<DOMFile*>(aBlob)->Impl();
+ DOMFileImpl* blobImpl = aBlob->Impl();
MOZ_ASSERT(blobImpl);
if (mReceivedBlobs.GetEntry(weakRef)) {
// This blob was previously retrieved from the database.
nsCOMPtr<nsIRemoteBlob> remoteBlob = do_QueryObject(blobImpl);
MOZ_ASSERT(remoteBlob);
BlobChild* blobChild = remoteBlob->GetBlobChild();
@@ -906,25 +907,25 @@ IDBDatabase::NoteFinishedFileActor(PBack
return PL_DHASH_NEXT;
}
};
mFileActors.Enumerate(&Helper::Remove, aFileActor);
}
void
-IDBDatabase::NoteReceivedBlob(nsIDOMBlob* aBlob)
+IDBDatabase::NoteReceivedBlob(DOMFile* aBlob)
{
AssertIsOnOwningThread();
MOZ_ASSERT(aBlob);
MOZ_ASSERT(mBackgroundActor);
#ifdef DEBUG
{
- nsRefPtr<DOMFileImpl> blobImpl = static_cast<DOMFile*>(aBlob)->Impl();
+ nsRefPtr<DOMFileImpl> blobImpl = aBlob->Impl();
MOZ_ASSERT(blobImpl);
nsCOMPtr<nsIRemoteBlob> remoteBlob = do_QueryObject(blobImpl);
MOZ_ASSERT(remoteBlob);
BlobChild* blobChild = remoteBlob->GetBlobChild();
MOZ_ASSERT(blobChild);
@@ -933,17 +934,18 @@ IDBDatabase::NoteReceivedBlob(nsIDOMBlob
PBackgroundChild* thisManager = mBackgroundActor->Manager()->Manager();
MOZ_ASSERT(thisManager);
MOZ_ASSERT(thisManager == backgroundManager);
}
#endif
- nsCOMPtr<nsIWeakReference> weakRef = do_GetWeakReference(aBlob);
+ nsCOMPtr<nsIDOMBlob> blob = aBlob;
+ nsCOMPtr<nsIWeakReference> weakRef = do_GetWeakReference(blob);
MOZ_ASSERT(weakRef);
// It's ok if this entry already exists in the table.
mReceivedBlobs.PutEntry(weakRef);
}
void
IDBDatabase::DelayedMaybeExpireFileActors()
--- a/dom/indexedDB/IDBDatabase.h
+++ b/dom/indexedDB/IDBDatabase.h
@@ -14,27 +14,27 @@
#include "mozilla/dom/quota/PersistenceType.h"
#include "nsAutoPtr.h"
#include "nsDataHashtable.h"
#include "nsHashKeys.h"
#include "nsString.h"
#include "nsTHashtable.h"
class nsIDocument;
-class nsIDOMBlob;
class nsIWeakReference;
class nsPIDOMWindow;
namespace mozilla {
class ErrorResult;
class EventChainPostVisitor;
namespace dom {
+class DOMFile;
class DOMStringList;
struct IDBObjectStoreParameters;
template <typename> class Sequence;
namespace indexedDB {
class BackgroundDatabaseChild;
class DatabaseSpec;
@@ -169,23 +169,23 @@ public:
void
UnregisterTransaction(IDBTransaction* aTransaction);
void
AbortTransactions();
PBackgroundIDBDatabaseFileChild*
- GetOrCreateFileActorForBlob(nsIDOMBlob* aBlob);
+ GetOrCreateFileActorForBlob(DOMFile* aBlob);
void
NoteFinishedFileActor(PBackgroundIDBDatabaseFileChild* aFileActor);
void
- NoteReceivedBlob(nsIDOMBlob* aBlob);
+ NoteReceivedBlob(DOMFile* aBlob);
void
DelayedMaybeExpireFileActors();
// XXX This doesn't really belong here... It's only needed for IDBMutableFile
// serialization and should be removed someday.
nsresult
GetQuotaInfo(nsACString& aOrigin, PersistenceType* aPersistenceType);
--- a/dom/indexedDB/IDBMutableFile.cpp
+++ b/dom/indexedDB/IDBMutableFile.cpp
@@ -346,17 +346,17 @@ IDBMutableFile::CreateFileObject(IDBFile
nsRefPtr<DOMFileImpl> impl =
new FileImplSnapshot(mName,
mType,
aMetadataParams,
mFile,
aFileHandle,
mFileInfo);
- nsCOMPtr<nsIDOMFile> fileSnapshot = new DOMFile(impl);
+ nsCOMPtr<nsIDOMFile> fileSnapshot = new DOMFile(GetOwner(), impl);
return fileSnapshot.forget();
}
already_AddRefed<DOMRequest>
IDBMutableFile::GetFile(ErrorResult& aError)
{
MOZ_ASSERT(NS_IsMainThread());
--- a/dom/indexedDB/IDBObjectStore.cpp
+++ b/dom/indexedDB/IDBObjectStore.cpp
@@ -25,16 +25,17 @@
#include "mozilla/Endian.h"
#include "mozilla/ErrorResult.h"
#include "mozilla/Move.h"
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/dom/ContentChild.h"
#include "mozilla/dom/ContentParent.h"
#include "mozilla/dom/DOMStringList.h"
#include "mozilla/dom/IDBMutableFileBinding.h"
+#include "mozilla/dom/BlobBinding.h"
#include "mozilla/dom/IDBObjectStoreBinding.h"
#include "mozilla/dom/StructuredCloneTags.h"
#include "mozilla/dom/indexedDB/PBackgroundIDBSharedTypes.h"
#include "mozilla/dom/ipc/BlobChild.h"
#include "mozilla/dom/ipc/BlobParent.h"
#include "mozilla/dom/ipc/nsIRemoteBlob.h"
#include "mozilla/ipc/BackgroundChild.h"
#include "mozilla/ipc/PBackgroundSharedTypes.h"
@@ -53,17 +54,17 @@ namespace indexedDB {
using namespace mozilla::dom::quota;
using namespace mozilla::ipc;
struct IDBObjectStore::StructuredCloneWriteInfo
{
struct BlobOrFileInfo
{
- nsCOMPtr<nsIDOMBlob> mBlob;
+ nsRefPtr<DOMFile> mBlob;
nsRefPtr<FileInfo> mFileInfo;
bool
operator==(const BlobOrFileInfo& aOther) const
{
return this->mBlob == aOther.mBlob && this->mFileInfo == aOther.mFileInfo;
}
};
@@ -292,82 +293,74 @@ StructuredCloneWriteCallback(JSContext*
cloneWriteInfo->mBlobOrFileInfos.AppendElement();
newBlobOrFileInfo->mFileInfo.swap(fileInfo);
return true;
}
MOZ_ASSERT(NS_IsMainThread(), "This can't work off the main thread!");
- nsCOMPtr<nsIXPConnectWrappedNative> wrappedNative;
- nsContentUtils::XPConnect()->
- GetWrappedNativeOfJSObject(aCx, aObj, getter_AddRefs(wrappedNative));
-
- if (wrappedNative) {
- nsISupports* supports = wrappedNative->Native();
-
- nsCOMPtr<nsIDOMBlob> blob = do_QueryInterface(supports);
- if (blob) {
+ {
+ DOMFile* blob = nullptr;
+ if (NS_SUCCEEDED(UNWRAP_OBJECT(Blob, aObj, blob))) {
uint64_t size;
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(blob->GetSize(&size)));
size = NativeEndian::swapToLittleEndian(size);
nsString type;
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(blob->GetType(type)));
NS_ConvertUTF16toUTF8 convType(type);
uint32_t convTypeLength =
NativeEndian::swapToLittleEndian(convType.Length());
- nsCOMPtr<nsIDOMFile> file = do_QueryInterface(blob);
-
if (cloneWriteInfo->mBlobOrFileInfos.Length() > size_t(UINT32_MAX)) {
MOZ_ASSERT(false,
"Fix the structured clone data to use a bigger type!");
return false;
}
const uint32_t index =
uint32_t(cloneWriteInfo->mBlobOrFileInfos.Length());
if (!JS_WriteUint32Pair(aWriter,
- file ? SCTAG_DOM_FILE : SCTAG_DOM_BLOB,
+ blob->IsFile() ? SCTAG_DOM_FILE : SCTAG_DOM_BLOB,
index) ||
!JS_WriteBytes(aWriter, &size, sizeof(size)) ||
!JS_WriteBytes(aWriter, &convTypeLength, sizeof(convTypeLength)) ||
!JS_WriteBytes(aWriter, convType.get(), convType.Length())) {
return false;
}
- if (file) {
+ if (blob->IsFile()) {
uint64_t lastModifiedDate;
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(
- file->GetMozLastModifiedDate(&lastModifiedDate)));
+ blob->GetMozLastModifiedDate(&lastModifiedDate)));
lastModifiedDate = NativeEndian::swapToLittleEndian(lastModifiedDate);
nsString name;
- MOZ_ALWAYS_TRUE(NS_SUCCEEDED(file->GetName(name)));
+ MOZ_ALWAYS_TRUE(NS_SUCCEEDED(blob->GetName(name)));
NS_ConvertUTF16toUTF8 convName(name);
uint32_t convNameLength =
NativeEndian::swapToLittleEndian(convName.Length());
if (!JS_WriteBytes(aWriter, &lastModifiedDate, sizeof(lastModifiedDate)) ||
!JS_WriteBytes(aWriter, &convNameLength, sizeof(convNameLength)) ||
!JS_WriteBytes(aWriter, convName.get(), convName.Length())) {
return false;
}
}
IDBObjectStore::StructuredCloneWriteInfo::BlobOrFileInfo*
newBlobOrFileInfo =
cloneWriteInfo->mBlobOrFileInfos.AppendElement();
- newBlobOrFileInfo->mBlob.swap(blob);
+ newBlobOrFileInfo->mBlob = blob;
return true;
}
}
// Try using the runtime callbacks
const JSStructuredCloneCallbacks* runtimeCallbacks =
js::GetContextStructuredCloneCallbacks(aCx);
@@ -403,22 +396,21 @@ GetAddInfoCallback(JSContext* aCx, void*
&data->mCloneWriteInfo)) {
return NS_ERROR_DOM_DATA_CLONE_ERR;
}
return NS_OK;
}
BlobChild*
-ActorFromRemoteBlob(nsIDOMBlob* aBlob)
+ActorFromRemoteBlob(DOMFile* aBlob)
{
MOZ_ASSERT(aBlob);
- nsRefPtr<DOMFile> blob = static_cast<DOMFile*>(aBlob);
- nsCOMPtr<nsIRemoteBlob> remoteBlob = do_QueryInterface(blob->Impl());
+ nsCOMPtr<nsIRemoteBlob> remoteBlob = do_QueryInterface(aBlob->Impl());
if (remoteBlob) {
BlobChild* actor = remoteBlob->GetBlobChild();
MOZ_ASSERT(actor);
if (actor->GetContentManager()) {
return nullptr;
}
@@ -430,32 +422,32 @@ ActorFromRemoteBlob(nsIDOMBlob* aBlob)
return actor;
}
return nullptr;
}
bool
-ResolveMysteryFile(nsIDOMBlob* aBlob,
+ResolveMysteryFile(DOMFile* aBlob,
const nsString& aName,
const nsString& aContentType,
uint64_t aSize,
uint64_t aLastModifiedDate)
{
BlobChild* actor = ActorFromRemoteBlob(aBlob);
if (actor) {
return actor->SetMysteryBlobInfo(aName, aContentType,
aSize, aLastModifiedDate);
}
return true;
}
bool
-ResolveMysteryBlob(nsIDOMBlob* aBlob,
+ResolveMysteryBlob(DOMFile* aBlob,
const nsString& aContentType,
uint64_t aSize)
{
BlobChild* actor = ActorFromRemoteBlob(aBlob);
if (actor) {
return actor->SetMysteryBlobInfo(aContentType, aSize);
}
return true;
@@ -599,67 +591,69 @@ public:
}
aResult.set(result);
return true;
}
static bool
CreateAndWrapBlobOrFile(JSContext* aCx,
+ IDBDatabase* aDatabase,
StructuredCloneFile& aFile,
const BlobOrFileData& aData,
JS::MutableHandle<JSObject*> aResult)
{
MOZ_ASSERT(aData.tag == SCTAG_DOM_FILE ||
aData.tag == SCTAG_DOM_FILE_WITHOUT_LASTMODIFIEDDATE ||
aData.tag == SCTAG_DOM_BLOB);
MOZ_ASSERT(aFile.mFile);
MOZ_ASSERT(NS_IsMainThread(),
"This wrapping currently only works on the main thread!");
+ // It can happen that this IDB is chrome code, so there is no parent, but
+ // still we want to set a correct parent for the new DOMFile object.
+ nsCOMPtr<nsISupports> parent;
+ if (aDatabase && aDatabase->GetParentObject()) {
+ parent = aDatabase->GetParentObject();
+ } else {
+ parent = xpc::NativeGlobal(JS::CurrentGlobalOrNull(aCx));
+ }
+
+ MOZ_ASSERT(parent);
+ nsRefPtr<DOMFile> file = new DOMFile(parent, aFile.mFile->Impl());
+
if (aData.tag == SCTAG_DOM_BLOB) {
if (NS_WARN_IF(!ResolveMysteryBlob(aFile.mFile,
aData.type,
aData.size))) {
return false;
}
JS::Rooted<JS::Value> wrappedBlob(aCx);
- nsresult rv =
- nsContentUtils::WrapNative(aCx,
- aFile.mFile,
- &NS_GET_IID(nsIDOMBlob),
- &wrappedBlob);
- if (NS_WARN_IF(NS_FAILED(rv))) {
+ if (!WrapNewBindingObject(aCx, aFile.mFile, &wrappedBlob)) {
return false;
}
aResult.set(&wrappedBlob.toObject());
return true;
}
- nsCOMPtr<nsIDOMFile> domFile = do_QueryInterface(aFile.mFile);
- MOZ_ASSERT(domFile);
+ MOZ_ASSERT(aFile.mFile->IsFile());
- if (NS_WARN_IF(!ResolveMysteryFile(domFile,
+ if (NS_WARN_IF(!ResolveMysteryFile(aFile.mFile,
aData.name,
aData.type,
aData.size,
aData.lastModifiedDate))) {
return false;
}
JS::Rooted<JS::Value> wrappedFile(aCx);
- nsresult rv =
- nsContentUtils::WrapNative(aCx,
- aFile.mFile,
- &NS_GET_IID(nsIDOMFile),
- &wrappedFile);
- if (NS_WARN_IF(NS_FAILED(rv))) {
+ if (!WrapNewBindingObject(aCx, aFile.mFile, &wrappedFile)) {
return false;
}
aResult.set(&wrappedFile.toObject());
return true;
}
};
@@ -684,16 +678,17 @@ public:
}
aResult.set(obj);
return true;
}
static bool
CreateAndWrapBlobOrFile(JSContext* aCx,
+ IDBDatabase* aDatabase,
StructuredCloneFile& aFile,
const BlobOrFileData& aData,
JS::MutableHandle<JSObject*> aResult)
{
MOZ_ASSERT(aData.tag == SCTAG_DOM_FILE ||
aData.tag == SCTAG_DOM_FILE_WITHOUT_LASTMODIFIEDDATE ||
aData.tag == SCTAG_DOM_BLOB);
@@ -810,16 +805,17 @@ CommonStructuredCloneReadCallback(JSCont
}
BlobOrFileData data;
if (NS_WARN_IF(!ReadBlobOrFile(aReader, aTag, &data))) {
return nullptr;
}
if (NS_WARN_IF(!Traits::CreateAndWrapBlobOrFile(aCx,
+ cloneReadInfo->mDatabase,
file,
data,
&result))) {
return nullptr;
}
return result;
}
--- a/dom/indexedDB/IDBRequest.cpp
+++ b/dom/indexedDB/IDBRequest.cpp
@@ -12,16 +12,17 @@
#include "IDBEvents.h"
#include "IDBFactory.h"
#include "IDBIndex.h"
#include "IDBObjectStore.h"
#include "IDBTransaction.h"
#include "mozilla/ContentEvents.h"
#include "mozilla/ErrorResult.h"
#include "mozilla/EventDispatcher.h"
+#include "mozilla/dom/DOMError.h"
#include "mozilla/dom/ErrorEventBinding.h"
#include "mozilla/dom/IDBOpenDBRequestBinding.h"
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/dom/UnionTypes.h"
#include "nsCOMPtr.h"
#include "nsContentUtils.h"
#include "nsIScriptContext.h"
#include "nsJSUtils.h"
--- a/dom/indexedDB/IDBTransaction.h
+++ b/dom/indexedDB/IDBTransaction.h
@@ -11,17 +11,16 @@
#include "mozilla/dom/IDBTransactionBinding.h"
#include "mozilla/dom/indexedDB/IDBWrapperCache.h"
#include "nsAutoPtr.h"
#include "nsCycleCollectionParticipant.h"
#include "nsIRunnable.h"
#include "nsString.h"
#include "nsTArray.h"
-class nsIDOMBlob;
class nsPIDOMWindow;
namespace mozilla {
class ErrorResult;
class EventChainPreVisitor;
namespace dom {
--- a/dom/indexedDB/IndexedDatabase.h
+++ b/dom/indexedDB/IndexedDatabase.h
@@ -9,32 +9,34 @@
#include "nsIProgrammingLanguage.h"
#include "js/StructuredClone.h"
#include "nsAutoPtr.h"
#include "nsCOMPtr.h"
#include "nsTArray.h"
-class nsIDOMBlob;
class nsIInputStream;
namespace mozilla {
namespace dom {
+
+class DOMFile;
+
namespace indexedDB {
class FileInfo;
class IDBDatabase;
class IDBTransaction;
class SerializedStructuredCloneReadInfo;
class SerializedStructuredCloneWriteInfo;
struct StructuredCloneFile
{
- nsCOMPtr<nsIDOMBlob> mFile;
+ nsRefPtr<DOMFile> mFile;
nsRefPtr<FileInfo> mFileInfo;
// In IndexedDatabaseInlines.h
inline
StructuredCloneFile();
// In IndexedDatabaseInlines.h
inline
--- a/dom/indexedDB/IndexedDatabaseInlines.h
+++ b/dom/indexedDB/IndexedDatabaseInlines.h
@@ -8,17 +8,17 @@
#define IndexedDatabaseInlines_h
#ifndef mozilla_dom_indexeddb_indexeddatabase_h__
#error Must include IndexedDatabase.h first
#endif
#include "FileInfo.h"
#include "mozilla/dom/indexedDB/PBackgroundIDBSharedTypes.h"
-#include "nsIDOMFile.h"
+#include "nsDOMFile.h"
#include "nsIInputStream.h"
namespace mozilla {
namespace dom {
namespace indexedDB {
inline
StructuredCloneFile::StructuredCloneFile()
--- a/dom/indexedDB/IndexedDatabaseManager.cpp
+++ b/dom/indexedDB/IndexedDatabaseManager.cpp
@@ -12,16 +12,17 @@
#include "nsIObserverService.h"
#include "nsIScriptError.h"
#include "jsapi.h"
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/CondVar.h"
#include "mozilla/ContentEvents.h"
#include "mozilla/dom/ContentChild.h"
+#include "mozilla/dom/DOMError.h"
#include "mozilla/dom/ErrorEventBinding.h"
#include "mozilla/dom/PBlobChild.h"
#include "mozilla/dom/quota/OriginOrPatternString.h"
#include "mozilla/dom/quota/QuotaManager.h"
#include "mozilla/dom/quota/Utilities.h"
#include "mozilla/dom/TabContext.h"
#include "mozilla/EventDispatcher.h"
#include "mozilla/ipc/BackgroundChild.h"
--- a/dom/indexedDB/test/unit/test_temporary_storage.js
+++ b/dom/indexedDB/test/unit/test_temporary_storage.js
@@ -1,13 +1,15 @@
/**
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
+Components.utils.importGlobalProperties(['Blob']);
+
var testGenerator = testSteps();
function testSteps()
{
const name = this.window ? window.location.pathname : "Splendid Test";
const urls = [
{ url: "http://www.alpha.com", flags: [true, true, true, true] },
--- a/dom/ipc/Blob.cpp
+++ b/dom/ipc/Blob.cpp
@@ -1042,33 +1042,30 @@ public:
MOZ_ASSERT(mActor);
mActor->AssertIsOnOwningThread();
mActor = nullptr;
}
NS_DECL_ISUPPORTS_INHERITED
- virtual nsresult
- GetMozFullPathInternal(nsAString &aFilePath) MOZ_OVERRIDE;
+ virtual void
+ GetMozFullPathInternal(nsAString& aFileName, ErrorResult& aRv) MOZ_OVERRIDE;
virtual already_AddRefed<DOMFileImpl>
- CreateSlice(uint64_t aStart, uint64_t aLength, const nsAString& aContentType)
- MOZ_OVERRIDE;
+ CreateSlice(uint64_t aStart, uint64_t aLength,
+ const nsAString& aContentType, ErrorResult& aRv) MOZ_OVERRIDE;
virtual nsresult
GetInternalStream(nsIInputStream** aStream) MOZ_OVERRIDE;
virtual int64_t
GetFileId() MOZ_OVERRIDE;
- virtual nsresult
- GetLastModifiedDate(JSContext* cx,
- JS::MutableHandle<JS::Value> aLastModifiedDate)
- MOZ_OVERRIDE;
+ virtual int64_t GetLastModified(ErrorResult& aRv) MOZ_OVERRIDE;
virtual BlobChild*
GetBlobChild() MOZ_OVERRIDE;
virtual BlobParent*
GetBlobParent() MOZ_OVERRIDE;
private:
@@ -1356,47 +1353,50 @@ private:
******************************************************************************/
NS_IMPL_ADDREF(BlobChild::RemoteBlobImpl)
NS_IMPL_RELEASE_WITH_DESTROY(BlobChild::RemoteBlobImpl, Destroy())
NS_IMPL_QUERY_INTERFACE_INHERITED(BlobChild::RemoteBlobImpl,
DOMFileImpl,
nsIRemoteBlob)
-nsresult
+void
BlobChild::
-RemoteBlobImpl::GetMozFullPathInternal(nsAString &aFilePath)
+RemoteBlobImpl::GetMozFullPathInternal(nsAString& aFilePath,
+ ErrorResult& aRv)
{
if (!mActor) {
- return NS_ERROR_UNEXPECTED;
+ aRv.Throw(NS_ERROR_UNEXPECTED);
+ return;
}
nsString filePath;
if (!mActor->SendGetFilePath(&filePath)) {
- return NS_ERROR_FAILURE;
+ aRv.Throw(NS_ERROR_FAILURE);
+ return;
}
aFilePath = filePath;
- return NS_OK;
}
already_AddRefed<DOMFileImpl>
BlobChild::
-RemoteBlobImpl::CreateSlice(uint64_t aStart,
- uint64_t aLength,
- const nsAString& aContentType)
+RemoteBlobImpl::CreateSlice(uint64_t aStart, uint64_t aLength,
+ const nsAString& aContentType, ErrorResult& aRv)
{
if (!mActor) {
+ aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
nsRefPtr<SliceHelper> helper = new SliceHelper(mActor);
nsRefPtr<DOMFileImpl> impl = helper->GetSlice(aStart, aLength, aContentType);
if (NS_WARN_IF(!impl)) {
+ aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
return impl.forget();
}
nsresult
BlobChild::
@@ -1417,32 +1417,25 @@ RemoteBlobImpl::GetFileId()
int64_t fileId;
if (mActor && mActor->SendGetFileId(&fileId)) {
return fileId;
}
return -1;
}
-nsresult
+int64_t
BlobChild::
-RemoteBlobImpl::GetLastModifiedDate(
- JSContext* cx,
- JS::MutableHandle<JS::Value> aLastModifiedDate)
+RemoteBlobImpl::GetLastModified(ErrorResult& aRv)
{
if (IsDateUnknown()) {
- aLastModifiedDate.setNull();
- } else {
- JSObject* date = JS_NewDateObjectMsec(cx, mLastModificationDate);
- if (!date) {
- return NS_ERROR_OUT_OF_MEMORY;
- }
- aLastModifiedDate.setObject(*date);
+ return 0;
}
- return NS_OK;
+
+ return mLastModificationDate;
}
BlobChild*
BlobChild::
RemoteBlobImpl::GetBlobChild()
{
return mActor;
}
@@ -1568,28 +1561,29 @@ BlobChild::CommonInit(BlobChild* aOther)
MOZ_ASSERT_IF(mBackgroundManager, aOther->GetContentManager());
MOZ_COUNT_CTOR(BlobChild);
nsRefPtr<DOMFileImpl> otherImpl = aOther->GetBlobImpl();
MOZ_ASSERT(otherImpl);
nsString contentType;
- MOZ_ALWAYS_TRUE(NS_SUCCEEDED(otherImpl->GetType(contentType)));
-
- uint64_t length;
- MOZ_ALWAYS_TRUE(NS_SUCCEEDED(otherImpl->GetSize(&length)));
+ otherImpl->GetType(contentType);
+
+ ErrorResult rv;
+ uint64_t length = otherImpl->GetSize(rv);
+ MOZ_ASSERT(!rv.Failed());
nsRefPtr<RemoteBlobImpl> remoteBlob;
if (otherImpl->IsFile()) {
nsString name;
- MOZ_ALWAYS_TRUE(NS_SUCCEEDED(otherImpl->GetName(name)));
-
- uint64_t modDate;
- MOZ_ALWAYS_TRUE(NS_SUCCEEDED(otherImpl->GetMozLastModifiedDate(&modDate)));
+ otherImpl->GetName(name);
+
+ uint64_t modDate = otherImpl->GetLastModified(rv);
+ MOZ_ASSERT(!rv.Failed());
remoteBlob = new RemoteBlobImpl(this, name, contentType, length, modDate);
} else {
remoteBlob = new RemoteBlobImpl(this, contentType, length);
}
MOZ_ASSERT(remoteBlob);
@@ -1750,31 +1744,32 @@ BlobChild::GetOrCreateFromImpl(ChildMana
}
MOZ_ASSERT(!aBlobImpl->IsSizeUnknown());
MOZ_ASSERT(!aBlobImpl->IsDateUnknown());
AnyBlobConstructorParams blobParams;
nsString contentType;
- MOZ_ALWAYS_TRUE(NS_SUCCEEDED(aBlobImpl->GetType(contentType)));
-
- uint64_t length;
- MOZ_ALWAYS_TRUE(NS_SUCCEEDED(aBlobImpl->GetSize(&length)));
+ aBlobImpl->GetType(contentType);
+
+ ErrorResult rv;
+ uint64_t length = aBlobImpl->GetSize(rv);
+ MOZ_ASSERT(!rv.Failed());
nsCOMPtr<nsIInputStream> stream;
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(
aBlobImpl->GetInternalStream(getter_AddRefs(stream))));
if (aBlobImpl->IsFile()) {
nsString name;
- MOZ_ALWAYS_TRUE(NS_SUCCEEDED(aBlobImpl->GetName(name)));
-
- uint64_t modDate;
- MOZ_ALWAYS_TRUE(NS_SUCCEEDED(aBlobImpl->GetMozLastModifiedDate(&modDate)));
+ aBlobImpl->GetName(name);
+
+ uint64_t modDate = aBlobImpl->GetLastModified(rv);
+ MOZ_ASSERT(!rv.Failed());
blobParams = FileBlobConstructorParams(name, contentType, length, modDate);
} else {
blobParams = NormalBlobConstructorParams(contentType, length);
}
InputStreamParams inputStreamParams;
@@ -1822,22 +1817,26 @@ BlobChild::CreateFromParams(ChildManager
auto* actor =
const_cast<BlobChild*>(
static_cast<const BlobChild*>(params.sourceChild()));
MOZ_ASSERT(actor);
nsRefPtr<DOMFileImpl> source = actor->GetBlobImpl();
MOZ_ASSERT(source);
- nsRefPtr<DOMFileImpl> slice;
- if (NS_WARN_IF(NS_FAILED(source->Slice(params.begin(),
- params.end(),
- params.contentType(),
- 3,
- getter_AddRefs(slice))))) {
+ Optional<int64_t> start;
+ start.Construct(params.begin());
+
+ Optional<int64_t> end;
+ start.Construct(params.end());
+
+ ErrorResult rv;
+ nsRefPtr<DOMFileImpl> slice =
+ source->Slice(start, end, params.contentType(), rv);
+ if (NS_WARN_IF(rv.Failed())) {
return nullptr;
}
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(slice->SetMutable(false)));
actor = new BlobChild(aManager, slice);
actor->mParentID = aParams.id();
@@ -1968,28 +1967,16 @@ BlobChild::GetBlobImpl()
blobImpl = mBlobImpl;
}
MOZ_ASSERT(blobImpl);
return blobImpl.forget();
}
-already_AddRefed<nsIDOMBlob>
-BlobChild::GetBlob()
-{
- AssertIsOnOwningThread();
-
- nsRefPtr<DOMFileImpl> blobImpl = GetBlobImpl();
- MOZ_ASSERT(blobImpl);
-
- nsCOMPtr<nsIDOMBlob> blob = new DOMFile(blobImpl);
- return blob.forget();
-}
-
bool
BlobChild::SetMysteryBlobInfo(const nsString& aName,
const nsString& aContentType,
uint64_t aLength,
uint64_t aLastModifiedDate)
{
AssertIsOnOwningThread();
MOZ_ASSERT(mBlobImpl);
@@ -2175,26 +2162,24 @@ class BlobParent::RemoteBlobImpl MOZ_FIN
class SliceHelper;
InputStreamParams mInputStreamParams;
public:
NS_DECL_ISUPPORTS_INHERITED
virtual already_AddRefed<DOMFileImpl>
- CreateSlice(uint64_t aStart, uint64_t aLength, const nsAString& aContentType)
- MOZ_OVERRIDE;
+ CreateSlice(uint64_t aStart, uint64_t aLength, const nsAString& aContentType,
+ ErrorResult& aRv) MOZ_OVERRIDE;
virtual nsresult
GetInternalStream(nsIInputStream** aStream) MOZ_OVERRIDE;
- virtual nsresult
- GetLastModifiedDate(JSContext* cx,
- JS::MutableHandle<JS::Value> aLastModifiedDate)
- MOZ_OVERRIDE;
+ virtual int64_t
+ GetLastModified(ErrorResult& aRv) MOZ_OVERRIDE;
virtual BlobChild*
GetBlobChild() MOZ_OVERRIDE;
virtual BlobParent*
GetBlobParent() MOZ_OVERRIDE;
private:
@@ -2380,71 +2365,65 @@ class BlobParent::ForwardingRemoteBlobIm
typedef mozilla::dom::indexedDB::FileManager FileManager;
nsRefPtr<DOMFileImpl> mBlobImpl;
nsCOMPtr<nsIRemoteBlob> mRemoteBlob;
public:
NS_DECL_ISUPPORTS_INHERITED
- virtual nsresult
+ virtual void
GetName(nsAString& aName) MOZ_OVERRIDE
{
- return mBlobImpl->GetName(aName);
+ mBlobImpl->GetName(aName);
}
virtual nsresult
GetPath(nsAString& aPath) MOZ_OVERRIDE
{
return mBlobImpl->GetPath(aPath);
}
- virtual nsresult
- GetLastModifiedDate(JSContext* aCx,
- JS::MutableHandle<JS::Value> aDate) MOZ_OVERRIDE
+ virtual int64_t
+ GetLastModified(ErrorResult& aRv) MOZ_OVERRIDE
{
- return mBlobImpl->GetLastModifiedDate(aCx, aDate);
+ return mBlobImpl->GetLastModified(aRv);
}
- virtual nsresult
- GetMozFullPath(nsAString& aName) MOZ_OVERRIDE
+ virtual void
+ GetMozFullPath(nsAString& aName, ErrorResult& aRv) MOZ_OVERRIDE
{
- return mBlobImpl->GetMozFullPath(aName);
+ mBlobImpl->GetMozFullPath(aName, aRv);
}
- virtual nsresult
- GetMozFullPathInternal(nsAString& aFileName) MOZ_OVERRIDE
+ virtual void
+ GetMozFullPathInternal(nsAString& aFileName, ErrorResult& aRv) MOZ_OVERRIDE
{
- return mBlobImpl->GetMozFullPathInternal(aFileName);
+ mBlobImpl->GetMozFullPathInternal(aFileName, aRv);
}
- virtual nsresult
- GetSize(uint64_t* aSize) MOZ_OVERRIDE
+ virtual uint64_t
+ GetSize(ErrorResult& aRv) MOZ_OVERRIDE
{
- return mBlobImpl->GetSize(aSize);
+ return mBlobImpl->GetSize(aRv);
}
- virtual nsresult
+ virtual void
GetType(nsAString& aType) MOZ_OVERRIDE
{
- return mBlobImpl->GetType(aType);
- }
-
- virtual nsresult
- GetMozLastModifiedDate(uint64_t* aDate) MOZ_OVERRIDE
- {
- return mBlobImpl->GetMozLastModifiedDate(aDate);
+ mBlobImpl->GetType(aType);
}
virtual already_AddRefed<DOMFileImpl>
CreateSlice(uint64_t aStart,
uint64_t aLength,
- const nsAString& aContentType) MOZ_OVERRIDE
+ const nsAString& aContentType,
+ ErrorResult& aRv) MOZ_OVERRIDE
{
- return mBlobImpl->CreateSlice(aStart, aLength, aContentType);
+ return mBlobImpl->CreateSlice(aStart, aLength, aContentType, aRv);
}
virtual const nsTArray<nsRefPtr<DOMFileImpl>>*
GetSubBlobImpls() const MOZ_OVERRIDE
{
return mBlobImpl->GetSubBlobImpls();
}
@@ -2524,25 +2503,16 @@ public:
}
virtual bool
IsFile() const MOZ_OVERRIDE
{
return mBlobImpl->IsFile();
}
- virtual nsresult
- Initialize(nsISupports* aOwner,
- JSContext* aCx,
- JSObject* aObj,
- const JS::CallArgs& aArgs) MOZ_OVERRIDE
- {
- MOZ_CRASH("This should never be called!");
- }
-
virtual void
Unlink() MOZ_OVERRIDE
{
return mBlobImpl->Unlink();
}
virtual void
Traverse(nsCycleCollectionTraversalCallback& aCallback) MOZ_OVERRIDE
@@ -2593,26 +2563,29 @@ NS_IMPL_RELEASE_WITH_DESTROY(BlobParent:
NS_IMPL_QUERY_INTERFACE_INHERITED(BlobParent::RemoteBlobImpl,
DOMFileImplBase,
nsIRemoteBlob)
already_AddRefed<DOMFileImpl>
BlobParent::
RemoteBlobImpl::CreateSlice(uint64_t aStart,
uint64_t aLength,
- const nsAString& aContentType)
+ const nsAString& aContentType,
+ ErrorResult& aRv)
{
if (!mActor) {
+ aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
nsRefPtr<SliceHelper> helper = new SliceHelper(mActor);
nsRefPtr<DOMFileImpl> impl = helper->GetSlice(aStart, aLength, aContentType);
if (NS_WARN_IF(!impl)) {
+ aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
return impl.forget();
}
nsresult
BlobParent::
@@ -2629,32 +2602,25 @@ RemoteBlobImpl::GetInternalStream(nsIInp
}
nsCOMPtr<nsIInputStream> stream =
new BlobInputStreamTether(realStream, this);
stream.forget(aStream);
return NS_OK;
}
-nsresult
+int64_t
BlobParent::
-RemoteBlobImpl::GetLastModifiedDate(
- JSContext* cx,
- JS::MutableHandle<JS::Value> aLastModifiedDate)
+RemoteBlobImpl::GetLastModified(ErrorResult& aRv)
{
if (IsDateUnknown()) {
- aLastModifiedDate.setNull();
- } else {
- JSObject* date = JS_NewDateObjectMsec(cx, mLastModificationDate);
- if (!date) {
- return NS_ERROR_OUT_OF_MEMORY;
- }
- aLastModifiedDate.setObject(*date);
+ return 0;
}
- return NS_OK;
+
+ return mLastModificationDate;
}
BlobChild*
BlobParent::
RemoteBlobImpl::GetBlobChild()
{
return nullptr;
}
@@ -2945,28 +2911,28 @@ BlobParent::GetOrCreateFromImpl(ParentMa
if (aBlobImpl->IsSizeUnknown() || aBlobImpl->IsDateUnknown()) {
// We don't want to call GetSize or GetLastModifiedDate yet since that may
// stat a file on the this thread. Instead we'll learn the size lazily from
// the other side.
blobParams = MysteryBlobConstructorParams();
} else {
nsString contentType;
- MOZ_ALWAYS_TRUE(NS_SUCCEEDED(aBlobImpl->GetType(contentType)));
-
- uint64_t length;
- MOZ_ALWAYS_TRUE(NS_SUCCEEDED(aBlobImpl->GetSize(&length)));
+ aBlobImpl->GetType(contentType);
+
+ ErrorResult rv;
+ uint64_t length = aBlobImpl->GetSize(rv);
+ MOZ_ASSERT(!rv.Failed());
if (aBlobImpl->IsFile()) {
nsString name;
- MOZ_ALWAYS_TRUE(NS_SUCCEEDED(aBlobImpl->GetName(name)));
-
- uint64_t modDate;
- MOZ_ALWAYS_TRUE(NS_SUCCEEDED(
- aBlobImpl->GetMozLastModifiedDate(&modDate)));
+ aBlobImpl->GetName(name);
+
+ uint64_t modDate = aBlobImpl->GetLastModified(rv);
+ MOZ_ASSERT(!rv.Failed());
blobParams =
FileBlobConstructorParams(name, contentType, length, modDate);
} else {
blobParams = NormalBlobConstructorParams(contentType, length);
}
}
@@ -3033,22 +2999,26 @@ BlobParent::CreateFromParams(ParentManag
auto* actor =
const_cast<BlobParent*>(
static_cast<const BlobParent*>(params.sourceParent()));
MOZ_ASSERT(actor);
nsRefPtr<DOMFileImpl> source = actor->GetBlobImpl();
MOZ_ASSERT(source);
- nsRefPtr<DOMFileImpl> slice;
- if (NS_WARN_IF(NS_FAILED(source->Slice(params.begin(),
- params.end(),
- params.contentType(),
- 3,
- getter_AddRefs(slice))))) {
+ Optional<int64_t> start;
+ start.Construct(params.begin());
+
+ Optional<int64_t> end;
+ end.Construct(params.end());
+
+ ErrorResult rv;
+ nsRefPtr<DOMFileImpl> slice =
+ source->Slice(start, end, params.contentType(), rv);
+ if (NS_WARN_IF(rv.Failed())) {
return nullptr;
}
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(slice->SetMutable(false)));
nsRefPtr<IDTableEntry> idTableEntry =
IDTableEntry::Create(params.optionalID(),
ActorManagerProcessID(aManager),
@@ -3162,30 +3132,16 @@ BlobParent::GetBlobImpl()
blobImpl = mBlobImpl;
}
MOZ_ASSERT(blobImpl);
return blobImpl.forget();
}
-already_AddRefed<nsIDOMBlob>
-BlobParent::GetBlob()
-{
- MOZ_ASSERT(!mBackgroundManager,
- "Don't call this method on a non-DOM thread! Use GetBlobImpl()!");
- AssertIsOnOwningThread();
-
- nsRefPtr<DOMFileImpl> blobImpl = GetBlobImpl();
- MOZ_ASSERT(blobImpl);
-
- nsCOMPtr<nsIDOMBlob> blob = new DOMFile(blobImpl);
- return blob.forget();
-}
-
void
BlobParent::NoteDyingRemoteBlobImpl()
{
MOZ_ASSERT(mRemoteBlobImpl);
MOZ_ASSERT(!mOwnsBlobImpl);
// This may be called on any thread due to the fact that RemoteBlobImpl is
// designed to be passed between threads. We must start the shutdown process
@@ -3473,18 +3429,19 @@ BlobParent::RecvGetFilePath(nsString* aF
#ifdef MOZ_CHILD_PERMISSIONS
if (NS_WARN_IF(!IndexedDatabaseManager::InTestingMode())) {
ASSERT_UNLESS_FUZZING();
return false;
}
#endif
nsString filePath;
- nsresult rv = mBlobImpl->GetMozFullPathInternal(filePath);
- if (NS_WARN_IF(NS_FAILED(rv))) {
+ ErrorResult rv;
+ mBlobImpl->GetMozFullPathInternal(filePath, rv);
+ if (NS_WARN_IF(rv.Failed())) {
return false;
}
*aFilePath = filePath;
return true;
}
bool
--- a/dom/ipc/BlobChild.h
+++ b/dom/ipc/BlobChild.h
@@ -100,20 +100,16 @@ public:
// Get the DOMFileImpl associated with this actor. This may always be called
// on the sending side. It may also be called on the receiving side unless
// this is a "mystery" blob that has not yet received a SetMysteryBlobInfo()
// call.
already_AddRefed<DOMFileImpl>
GetBlobImpl();
- // XXX This method will be removed soon.
- already_AddRefed<nsIDOMBlob>
- GetBlob();
-
// Use this for files.
bool
SetMysteryBlobInfo(const nsString& aName,
const nsString& aContentType,
uint64_t aLength,
uint64_t aLastModifiedDate);
// Use this for non-file blobs.
--- a/dom/ipc/BlobParent.h
+++ b/dom/ipc/BlobParent.h
@@ -124,21 +124,16 @@ public:
{
return mContentManager;
}
// Get the DOMFileImpl associated with this actor.
already_AddRefed<DOMFileImpl>
GetBlobImpl();
- // XXX This method will be removed soon. It may never be called on a non-DOM
- // thread.
- already_AddRefed<nsIDOMBlob>
- GetBlob();
-
void
AssertIsOnOwningThread() const
#ifdef DEBUG
;
#else
{ }
#endif
--- a/dom/ipc/FilePickerParent.cpp
+++ b/dom/ipc/FilePickerParent.cpp
@@ -112,17 +112,18 @@ FilePickerParent::FileSizeAndDateRunnabl
void
FilePickerParent::SendFiles(const nsCOMArray<nsIDOMFile>& aDomfiles)
{
nsIContentParent* parent = static_cast<TabParent*>(Manager())->Manager();
InfallibleTArray<PBlobParent*> files;
for (unsigned i = 0; i < aDomfiles.Length(); i++) {
- BlobParent* blob = parent->GetOrCreateActorForBlob(aDomfiles[i]);
+ BlobParent* blob = parent->GetOrCreateActorForBlob(
+ static_cast<DOMFile*>(aDomfiles[i]));
if (blob) {
files.AppendElement(blob);
}
}
InputFiles infiles;
infiles.filesParent().SwapElements(files);
unused << Send__delete__(this, infiles, mResult);
@@ -144,25 +145,30 @@ FilePickerParent::Done(int16_t aResult)
NS_ENSURE_SUCCESS_VOID(mFilePicker->GetFiles(getter_AddRefs(iter)));
nsCOMPtr<nsISupports> supports;
bool loop = true;
while (NS_SUCCEEDED(iter->HasMoreElements(&loop)) && loop) {
iter->GetNext(getter_AddRefs(supports));
if (supports) {
nsCOMPtr<nsIFile> file = do_QueryInterface(supports);
- nsCOMPtr<nsIDOMFile> domfile = DOMFile::CreateFromFile(file);
+
+ // A null parent is fine because DOMFile are not used in this process
+ // but only in the child.
+ nsCOMPtr<nsIDOMFile> domfile = DOMFile::CreateFromFile(nullptr, file);
domfiles.AppendElement(domfile);
}
}
} else {
nsCOMPtr<nsIFile> file;
mFilePicker->GetFile(getter_AddRefs(file));
if (file) {
- nsCOMPtr<nsIDOMFile> domfile = DOMFile::CreateFromFile(file);
+ // A null parent is fine because DOMFile are not used in this process
+ // but only in the child.
+ nsCOMPtr<nsIDOMFile> domfile = DOMFile::CreateFromFile(nullptr, file);
domfiles.AppendElement(domfile);
}
}
MOZ_ASSERT(!mRunnable);
mRunnable = new FileSizeAndDateRunnable(this, domfiles);
if (!mRunnable->Dispatch()) {
unused << Send__delete__(this, void_t(), nsIFilePicker::returnCancel);
--- a/dom/ipc/StructuredCloneUtils.cpp
+++ b/dom/ipc/StructuredCloneUtils.cpp
@@ -1,21 +1,22 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* vim: set sw=4 ts=8 et tw=80 : */
/* 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 "StructuredCloneUtils.h"
-#include "nsIDOMFile.h"
#include "nsIDOMDOMException.h"
#include "nsIMutable.h"
#include "nsIXPConnect.h"
+#include "mozilla/dom/BlobBinding.h"
+#include "nsDOMFile.h"
#include "nsContentUtils.h"
#include "nsJSEnvironment.h"
#include "MainThreadUtils.h"
#include "StructuredCloneTags.h"
#include "jsapi.h"
using namespace mozilla::dom;
@@ -33,117 +34,71 @@ Read(JSContext* aCx, JSStructuredCloneRe
uint32_t aData, void* aClosure)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aClosure);
StructuredCloneClosure* closure =
static_cast<StructuredCloneClosure*>(aClosure);
- if (aTag == SCTAG_DOM_FILE) {
- MOZ_ASSERT(aData < closure->mBlobs.Length());
-
- nsCOMPtr<nsIDOMFile> file = do_QueryInterface(closure->mBlobs[aData]);
- MOZ_ASSERT(file);
+ if (aTag == SCTAG_DOM_BLOB) {
+ // nsRefPtr<DOMFile> needs to go out of scope before toObjectOrNull() is
+ // called because the static analysis thinks dereferencing XPCOM objects
+ // can GC (because in some cases it can!), and a return statement with a
+ // JSObject* type means that JSObject* is on the stack as a raw pointer
+ // while destructors are running.
+ JS::Rooted<JS::Value> val(aCx);
+ {
+ MOZ_ASSERT(aData < closure->mBlobs.Length());
+ nsRefPtr<DOMFile> blob = closure->mBlobs[aData];
#ifdef DEBUG
- {
- // File should not be mutable.
- nsCOMPtr<nsIMutable> mutableFile = do_QueryInterface(file);
- bool isMutable;
- MOZ_ASSERT(NS_SUCCEEDED(mutableFile->GetMutable(&isMutable)));
- MOZ_ASSERT(!isMutable);
- }
+ {
+ // File should not be mutable.
+ bool isMutable;
+ MOZ_ASSERT(NS_SUCCEEDED(blob->GetMutable(&isMutable)));
+ MOZ_ASSERT(!isMutable);
+ }
#endif
- JS::Rooted<JS::Value> wrappedFile(aCx);
- nsresult rv = nsContentUtils::WrapNative(aCx, file, &NS_GET_IID(nsIDOMFile),
- &wrappedFile);
- if (NS_FAILED(rv)) {
- Error(aCx, nsIDOMDOMException::DATA_CLONE_ERR);
- return nullptr;
+ // Let's create a new blob with the correct parent.
+ nsIGlobalObject *global = xpc::NativeGlobal(JS::CurrentGlobalOrNull(aCx));
+ MOZ_ASSERT(global);
+
+ nsRefPtr<DOMFile> newBlob = new DOMFile(global, blob->Impl());
+ if (!WrapNewBindingObject(aCx, newBlob, &val)) {
+ return nullptr;
+ }
}
- return &wrappedFile.toObject();
- }
-
- if (aTag == SCTAG_DOM_BLOB) {
- MOZ_ASSERT(aData < closure->mBlobs.Length());
-
- nsCOMPtr<nsIDOMBlob> blob = do_QueryInterface(closure->mBlobs[aData]);
- MOZ_ASSERT(blob);
-
-#ifdef DEBUG
- {
- // Blob should not be mutable.
- nsCOMPtr<nsIMutable> mutableBlob = do_QueryInterface(blob);
- bool isMutable;
- MOZ_ASSERT(NS_SUCCEEDED(mutableBlob->GetMutable(&isMutable)));
- MOZ_ASSERT(!isMutable);
- }
-#endif
-
- JS::Rooted<JS::Value> wrappedBlob(aCx);
- nsresult rv = nsContentUtils::WrapNative(aCx, blob, &NS_GET_IID(nsIDOMBlob),
- &wrappedBlob);
- if (NS_FAILED(rv)) {
- Error(aCx, nsIDOMDOMException::DATA_CLONE_ERR);
- return nullptr;
- }
-
- return &wrappedBlob.toObject();
+ return &val.toObject();
}
return NS_DOMReadStructuredClone(aCx, aReader, aTag, aData, nullptr);
}
bool
Write(JSContext* aCx, JSStructuredCloneWriter* aWriter,
JS::Handle<JSObject*> aObj, void* aClosure)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aClosure);
StructuredCloneClosure* closure =
static_cast<StructuredCloneClosure*>(aClosure);
- // See if this is a wrapped native.
- nsCOMPtr<nsIXPConnectWrappedNative> wrappedNative;
- nsContentUtils::XPConnect()->
- GetWrappedNativeOfJSObject(aCx, aObj, getter_AddRefs(wrappedNative));
-
- if (wrappedNative) {
- // Get the raw nsISupports out of it.
- nsISupports* wrappedObject = wrappedNative->Native();
- MOZ_ASSERT(wrappedObject);
-
- // See if the wrapped native is a nsIDOMFile.
- nsCOMPtr<nsIDOMFile> file = do_QueryInterface(wrappedObject);
- if (file) {
- nsCOMPtr<nsIMutable> mutableFile = do_QueryInterface(file);
- if (mutableFile &&
- NS_SUCCEEDED(mutableFile->SetMutable(false)) &&
- JS_WriteUint32Pair(aWriter, SCTAG_DOM_FILE,
- closure->mBlobs.Length())) {
- closure->mBlobs.AppendElement(file);
- return true;
- }
- }
-
- // See if the wrapped native is a nsIDOMBlob.
- nsCOMPtr<nsIDOMBlob> blob = do_QueryInterface(wrappedObject);
- if (blob) {
- nsCOMPtr<nsIMutable> mutableBlob = do_QueryInterface(blob);
- if (mutableBlob &&
- NS_SUCCEEDED(mutableBlob->SetMutable(false)) &&
- JS_WriteUint32Pair(aWriter, SCTAG_DOM_BLOB,
- closure->mBlobs.Length())) {
- closure->mBlobs.AppendElement(blob);
- return true;
- }
+ // See if the wrapped native is a DOMFile/Blob.
+ {
+ DOMFile* blob = nullptr;
+ if (NS_SUCCEEDED(UNWRAP_OBJECT(Blob, aObj, blob)) &&
+ NS_SUCCEEDED(blob->SetMutable(false)) &&
+ JS_WriteUint32Pair(aWriter, SCTAG_DOM_BLOB,
+ closure->mBlobs.Length())) {
+ closure->mBlobs.AppendElement(blob);
+ return true;
}
}
return NS_DOMWriteStructuredClone(aCx, aWriter, aObj, nullptr);
}
JSStructuredCloneCallbacks gCallbacks = {
Read,
--- a/dom/ipc/StructuredCloneUtils.h
+++ b/dom/ipc/StructuredCloneUtils.h
@@ -4,30 +4,30 @@
* 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/. */
#ifndef mozilla_dom_StructuredCloneUtils_h
#define mozilla_dom_StructuredCloneUtils_h
#include "nsCOMPtr.h"
#include "nsTArray.h"
-#include "nsIDOMFile.h"
+#include "nsDOMFile.h"
#include "js/StructuredClone.h"
namespace mozilla {
struct SerializedStructuredCloneBuffer;
namespace dom {
struct
StructuredCloneClosure
{
- nsTArray<nsCOMPtr<nsIDOMBlob> > mBlobs;
+ nsTArray<nsRefPtr<DOMFile>> mBlobs;
};
struct
StructuredCloneData
{
StructuredCloneData() : mData(nullptr), mDataLength(0) {}
uint64_t* mData;
size_t mDataLength;
--- a/dom/ipc/nsIContentChild.cpp
+++ b/dom/ipc/nsIContentChild.cpp
@@ -92,22 +92,22 @@ nsIContentChild::AllocPBlobChild(const B
bool
nsIContentChild::DeallocPBlobChild(PBlobChild* aActor)
{
BlobChild::Destroy(aActor);
return true;
}
BlobChild*
-nsIContentChild::GetOrCreateActorForBlob(nsIDOMBlob* aBlob)
+nsIContentChild::GetOrCreateActorForBlob(DOMFile* aBlob)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aBlob);
- nsRefPtr<DOMFileImpl> blobImpl = static_cast<DOMFile*>(aBlob)->Impl();
+ nsRefPtr<DOMFileImpl> blobImpl = aBlob->Impl();
MOZ_ASSERT(blobImpl);
BlobChild* actor = BlobChild::GetOrCreate(this, blobImpl);
NS_ENSURE_TRUE(actor, nullptr);
return actor;
}
--- a/dom/ipc/nsIContentChild.h
+++ b/dom/ipc/nsIContentChild.h
@@ -10,17 +10,16 @@
#include "nsISupports.h"
#include "nsTArrayForwardDeclare.h"
#include "mozilla/dom/CPOWManagerGetter.h"
#define NS_ICONTENTCHILD_IID \
{ 0x4eed2e73, 0x94ba, 0x48a8, \
{ 0xa2, 0xd1, 0xa5, 0xed, 0x86, 0xd7, 0xbb, 0xe4 } }
-class nsIDOMBlob;
class nsString;
namespace IPC {
class Principal;
} // IPC
namespace mozilla {
@@ -29,27 +28,28 @@ class PJavaScriptChild;
class CpowEntry;
} // jsipc
namespace dom {
class BlobChild;
class BlobConstructorParams;
class ClonedMessageData;
+class DOMFile;
class IPCTabContext;
class PBlobChild;
class PBrowserChild;
class nsIContentChild : public nsISupports
, public CPOWManagerGetter
{
public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_ICONTENTCHILD_IID)
- BlobChild* GetOrCreateActorForBlob(nsIDOMBlob* aBlob);
+ BlobChild* GetOrCreateActorForBlob(DOMFile* aBlob);
virtual PBlobChild* SendPBlobConstructor(
PBlobChild* aActor,
const BlobConstructorParams& aParams) = 0;
virtual bool
SendPBrowserConstructor(PBrowserChild* aActor,
const IPCTabContext& aContext,
--- a/dom/ipc/nsIContentParent.cpp
+++ b/dom/ipc/nsIContentParent.cpp
@@ -146,22 +146,22 @@ nsIContentParent::AllocPBlobParent(const
bool
nsIContentParent::DeallocPBlobParent(PBlobParent* aActor)
{
BlobParent::Destroy(aActor);
return true;
}
BlobParent*
-nsIContentParent::GetOrCreateActorForBlob(nsIDOMBlob* aBlob)
+nsIContentParent::GetOrCreateActorForBlob(DOMFile* aBlob)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aBlob);
- nsRefPtr<DOMFileImpl> blobImpl = static_cast<DOMFile*>(aBlob)->Impl();
+ nsRefPtr<DOMFileImpl> blobImpl = aBlob->Impl();
MOZ_ASSERT(blobImpl);
BlobParent* actor = BlobParent::GetOrCreate(this, blobImpl);
NS_ENSURE_TRUE(actor, nullptr);
return actor;
}
--- a/dom/ipc/nsIContentParent.h
+++ b/dom/ipc/nsIContentParent.h
@@ -11,17 +11,16 @@
#include "nsISupports.h"
#include "mozilla/dom/CPOWManagerGetter.h"
#define NS_ICONTENTPARENT_IID \
{ 0xeeec9ebf, 0x8ecf, 0x4e38, \
{ 0x81, 0xda, 0xb7, 0x34, 0x13, 0x7e, 0xac, 0xf3 } }
class nsFrameMessageManager;
-class nsIDOMBlob;
namespace IPC {
class Principal;
} // namespace IPC
namespace mozilla {
namespace jsipc {
@@ -29,30 +28,31 @@ class PJavaScriptParent;
class CpowEntry;
} // namespace jsipc
namespace dom {
class BlobConstructorParams;
class BlobParent;
class ContentParent;
+class DOMFile;
class IPCTabContext;
class PBlobParent;
class PBrowserParent;
class nsIContentParent : public nsISupports
, public mozilla::dom::ipc::MessageManagerCallback
, public CPOWManagerGetter
{
public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_ICONTENTPARENT_IID)
nsIContentParent();
- BlobParent* GetOrCreateActorForBlob(nsIDOMBlob* aBlob);
+ BlobParent* GetOrCreateActorForBlob(DOMFile* aBlob);
virtual uint64_t ChildID() = 0;
virtual bool IsForApp() = 0;
virtual bool IsForBrowser() = 0;
virtual PBlobParent* SendPBlobConstructor(
PBlobParent* aActor,
const BlobConstructorParams& aParams) NS_WARN_UNUSED_RESULT = 0;
--- a/dom/mobilemessage/MmsMessage.cpp
+++ b/dom/mobilemessage/MmsMessage.cpp
@@ -86,20 +86,25 @@ MmsMessage::MmsMessage(const mobilemessa
{
uint32_t len = aData.attachments().Length();
mAttachments.SetCapacity(len);
for (uint32_t i = 0; i < len; i++) {
MmsAttachment att;
const MmsAttachmentData &element = aData.attachments()[i];
att.mId = element.id();
att.mLocation = element.location();
+
+ // mContent is not going to be exposed to JS directly so we can use
+ // nullptr as parent.
if (element.contentParent()) {
- att.mContent = static_cast<BlobParent*>(element.contentParent())->GetBlob();
+ nsRefPtr<DOMFileImpl> impl = static_cast<BlobParent*>(element.contentParent())->GetBlobImpl();
+ att.mContent = new DOMFile(nullptr, impl);
} else if (element.contentChild()) {
- att.mContent = static_cast<BlobChild*>(element.contentChild())->GetBlob();
+ nsRefPtr<DOMFileImpl> impl = static_cast<BlobChild*>(element.contentChild())->GetBlobImpl();
+ att.mContent = new DOMFile(nullptr, impl);
} else {
NS_WARNING("MmsMessage: Unable to get attachment content.");
}
mAttachments.AppendElement(att);
}
len = aData.deliveryInfo().Length();
mDeliveryInfo.SetCapacity(len);
@@ -382,20 +387,19 @@ MmsMessage::GetData(ContentParent* aPare
const Attachment &element = mAttachments[i];
mma.id().Assign(element.id);
mma.location().Assign(element.location);
// This is a workaround. Sometimes the blob we get from the database
// doesn't have a valid last modified date, making the ContentParent
// send a "Mystery Blob" to the ContentChild. Attempting to get the
// last modified date of blob can force that value to be initialized.
- DOMFile* file = static_cast<DOMFile*>(element.content.get());
- if (file->IsDateUnknown()) {
+ if (element.content->IsDateUnknown()) {
uint64_t date;
- if (NS_FAILED(file->GetMozLastModifiedDate(&date))) {
+ if (NS_FAILED(element.content->GetMozLastModifiedDate(&date))) {
NS_WARNING("Failed to get last modified date!");
}
}
mma.contentParent() = aParent->GetOrCreateActorForBlob(element.content);
if (!mma.contentParent()) {
return false;
}
@@ -567,24 +571,28 @@ MmsMessage::GetAttachments(JSContext* aC
attachment.location.Length());
NS_ENSURE_TRUE(tmpJsStr, NS_ERROR_OUT_OF_MEMORY);
if (!JS_DefineProperty(aCx, attachmentObj, "location", tmpJsStr, JSPROP_ENUMERATE)) {
return NS_ERROR_FAILURE;
}
// Get |attachment.mContent|.
- JS::Rooted<JS::Value> tmpJsVal(aCx);
- nsresult rv = nsContentUtils::WrapNative(aCx,
- attachment.content,
- &NS_GET_IID(nsIDOMBlob),
- &tmpJsVal);
- NS_ENSURE_SUCCESS(rv, rv);
+
+ // Duplicating the DOMFile with the correct parent object.
+ nsIGlobalObject *global = xpc::NativeGlobal(JS::CurrentGlobalOrNull(aCx));
+ MOZ_ASSERT(global);
+ nsRefPtr<DOMFile> newBlob = new DOMFile(global, attachment.content->Impl());
- if (!JS_DefineProperty(aCx, attachmentObj, "content", tmpJsVal, JSPROP_ENUMERATE)) {
+ JS::Rooted<JS::Value> val(aCx);
+ if (!WrapNewBindingObject(aCx, newBlob, &val)) {
+ return NS_ERROR_FAILURE;
+ }
+
+ if (!JS_DefineProperty(aCx, attachmentObj, "content", val, JSPROP_ENUMERATE)) {
return NS_ERROR_FAILURE;
}
if (!JS_SetElement(aCx, attachments, i, attachmentObj)) {
return NS_ERROR_FAILURE;
}
}
--- a/dom/mobilemessage/MmsMessage.h
+++ b/dom/mobilemessage/MmsMessage.h
@@ -11,32 +11,34 @@
#include "mozilla/dom/mobilemessage/Types.h"
#include "mozilla/dom/MozMmsMessageBinding.h"
#include "mozilla/dom/MozMobileMessageManagerBinding.h"
#include "mozilla/Attributes.h"
namespace mozilla {
namespace dom {
+class DOMFile;
+
namespace mobilemessage {
class MmsMessageData;
} // namespace mobilemessage
class ContentParent;
class MmsMessage MOZ_FINAL : public nsIDOMMozMmsMessage
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIDOMMOZMMSMESSAGE
// If this is changed, change the WebIDL dictionary as well.
struct Attachment MOZ_FINAL
{
- nsCOMPtr<nsIDOMBlob> content;
+ nsRefPtr<DOMFile> content;
nsString id;
nsString location;
explicit Attachment(const MmsAttachment& aAttachment) :
content(aAttachment.mContent),
id(aAttachment.mId),
location(aAttachment.mLocation)
{}
--- a/dom/mobilemessage/gonk/WspPduHelper.jsm
+++ b/dom/mobilemessage/gonk/WspPduHelper.jsm
@@ -1,16 +1,17 @@
/* 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/. */
"use strict";
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
+Cu.importGlobalProperties(['Blob']);
Cu.import("resource://gre/modules/wap_consts.js", this);
let DEBUG; // set to true to see debug messages
// Special ASCII characters
const NUL = 0;
const CR = 13;
const LF = 10;
--- a/dom/mobilemessage/ipc/SmsParent.cpp
+++ b/dom/mobilemessage/ipc/SmsParent.cpp
@@ -48,23 +48,34 @@ MmsAttachmentDataToJSObject(JSContext* a
JS::Rooted<JSString*> locStr(aContext, JS_NewUCStringCopyN(aContext,
aAttachment.location().get(),
aAttachment.location().Length()));
NS_ENSURE_TRUE(locStr, nullptr);
if (!JS_DefineProperty(aContext, obj, "location", locStr, 0)) {
return nullptr;
}
- nsCOMPtr<nsIDOMBlob> blob = static_cast<BlobParent*>(aAttachment.contentParent())->GetBlob();
+ nsRefPtr<DOMFileImpl> blobImpl = static_cast<BlobParent*>(aAttachment.contentParent())->GetBlobImpl();
+
+ // nsRefPtr<DOMFile> needs to go out of scope before toObjectOrNull() is
+ // called because the static analysis thinks dereferencing XPCOM objects
+ // can GC (because in some cases it can!), and a return statement with a
+ // JSObject* type means that JSObject* is on the stack as a raw pointer
+ // while destructors are running.
JS::Rooted<JS::Value> content(aContext);
- nsresult rv = nsContentUtils::WrapNative(aContext,
- blob,
- &NS_GET_IID(nsIDOMBlob),
- &content);
- NS_ENSURE_SUCCESS(rv, nullptr);
+ {
+ nsIGlobalObject *global = xpc::NativeGlobal(JS::CurrentGlobalOrNull(aContext));
+ MOZ_ASSERT(global);
+
+ nsRefPtr<DOMFile> blob = new DOMFile(global, blobImpl);
+ if (!WrapNewBindingObject(aContext, blob, &content)) {
+ return nullptr;
+ }
+ }
+
if (!JS_DefineProperty(aContext, obj, "content", content, 0)) {
return nullptr;
}
return obj;
}
static bool
--- a/dom/network/UDPSocket.cpp
+++ b/dom/network/UDPSocket.cpp
@@ -8,17 +8,17 @@
#include "mozilla/AsyncEventDispatcher.h"
#include "mozilla/dom/ErrorEvent.h"
#include "mozilla/dom/UDPMessageEvent.h"
#include "mozilla/dom/UDPSocketBinding.h"
#include "mozilla/dom/UnionTypes.h"
#include "mozilla/net/DNS.h"
#include "nsComponentManagerUtils.h"
#include "nsContentUtils.h"
-#include "nsIDOMFile.h"
+#include "nsDOMFile.h"
#include "nsINetAddr.h"
#include "nsStringStream.h"
namespace mozilla {
namespace dom {
NS_IMPL_CYCLE_COLLECTION_CLASS(UDPSocket)
@@ -323,19 +323,19 @@ UDPSocket::Send(const StringOrBlobOrArra
remotePort = mRemotePort.Value();
} else {
aRv.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR);
return false;
}
nsCOMPtr<nsIInputStream> stream;
if (aData.IsBlob()) {
- nsCOMPtr<nsIDOMBlob> blob = aData.GetAsBlob();
+ DOMFile& blob = aData.GetAsBlob();
- aRv = blob->GetInternalStream(getter_AddRefs(stream));
+ aRv = blob.GetInternalStream(getter_AddRefs(stream));
if (NS_WARN_IF(aRv.Failed())) {
return false;
}
} else {
nsresult rv;
nsCOMPtr<nsIStringInputStream> strStream = do_CreateInstance(NS_STRINGINPUTSTREAM_CONTRACTID, &rv);
if (NS_WARN_IF(NS_FAILED(rv))) {
aRv.Throw(rv);
--- a/dom/settings/SettingsDB.jsm
+++ b/dom/settings/SettingsDB.jsm
@@ -3,16 +3,17 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
let Cc = Components.classes;
let Ci = Components.interfaces;
let Cu = Components.utils;
+Cu.importGlobalProperties(['Blob']);
Cu.import("resource://gre/modules/Services.jsm");
this.EXPORTED_SYMBOLS = ["SettingsDB", "SETTINGSDB_NAME", "SETTINGSSTORE_NAME"];
const DEBUG = false;
function debug(s) {
if (DEBUG) dump("-*- SettingsDB: " + s + "\n");
}
--- a/dom/webidl/Blob.webidl
+++ b/dom/webidl/Blob.webidl
@@ -5,32 +5,37 @@
*
* The origin of this IDL file is
* http://dev.w3.org/2006/webapi/FileAPI/#blob
*
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
* liability, trademark and document use rules apply.
*/
-/*
-[Constructor, Constructor((ArrayBuffer or ArrayBufferView or Blob or DOMString)[] blobParts, optional BlobPropertyBag options)]
+[Constructor,
+ Constructor(sequence<(ArrayBuffer or ArrayBufferView or Blob or DOMString)> blobParts, optional BlobPropertyBag options),
+ Exposed=(Window,Worker)]
interface Blob {
+ [GetterThrows]
readonly attribute unsigned long long size;
+
readonly attribute DOMString type;
+ // readonly attribute boolean isClosed; TODO bug 1048321
+
//slice Blob into byte-ranged chunks
- Blob slice(optional long long start,
- optional long long end,
- optional DOMString contentType);
- void close();
+ [Throws]
+ Blob slice([Clamp] optional long long start,
+ [Clamp] optional long long end,
+ optional DOMString contentType = "");
+ // void close(); TODO bug 1048325
};
-*/
enum EndingTypes{"transparent", "native"};
dictionary BlobPropertyBag {
DOMString type = "";
EndingTypes endings = "transparent";
--- a/dom/webidl/BlobEvent.webidl
+++ b/dom/webidl/BlobEvent.webidl
@@ -1,14 +1,13 @@
/* -*- 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/.
*/
-interface Blob;
[Constructor(DOMString type, optional BlobEventInit eventInitDict)]
interface BlobEvent : Event
{
readonly attribute Blob? data;
};
dictionary BlobEventInit : EventInit
--- a/dom/webidl/Directory.webidl
+++ b/dom/webidl/Directory.webidl
@@ -1,16 +1,14 @@
/* -*- 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/.
*/
-interface File;
-
/*
* All functions on Directory that accept DOMString arguments for file or
* directory names only allow relative path to current directory itself. The
* path should be a descendent path like "path/to/file.txt" and not contain a
* segment of ".." or ".". So the paths aren't allowed to walk up the directory
* tree. For example, paths like "../foo", "..", "/foo/bar" or "foo/../bar" are
* not allowed.
*/
--- a/dom/webidl/File.webidl
+++ b/dom/webidl/File.webidl
@@ -1,9 +1,45 @@
/* -*- 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 = "";
+interface nsIFile;
+
+[Constructor(sequence<(ArrayBuffer or ArrayBufferView or Blob or DOMString)> fileBits,
+ ScalarValueString fileName, optional FilePropertyBag options),
+
+ // These constructors are just for chrome callers:
+ Constructor(Blob fileBits, optional FilePropertyBag options),
+ Constructor(nsIFile fileBits, optional FilePropertyBag options),
+ Constructor(ScalarValueString fileBits, optional FilePropertyBag options),
+
+ Exposed=(Window,Worker)]
+interface File : Blob {
+
+ readonly attribute DOMString name;
+
+ [GetterThrows]
+ readonly attribute long long lastModified;
+
};
+
+
+dictionary FilePropertyBag {
+
+ DOMString type = "";
+ DOMString name = ""; // TODO: to remove!
+ long long lastModified;
+
+};
+
+// Mozilla extensions
+partial interface File {
+
+ [GetterThrows]
+ readonly attribute Date lastModifiedDate;
+
+ [GetterThrows]
+ readonly attribute DOMString mozFullPath;
+
+};
--- a/dom/webidl/FileList.webidl
+++ b/dom/webidl/FileList.webidl
@@ -5,14 +5,12 @@
*
* The origin of this IDL file is
* http://dev.w3.org/2006/webapi/FileAPI/
*
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
* liability, trademark and document use rules apply.
*/
-interface File;
-
interface FileList {
getter File? item(unsigned long index);
readonly attribute unsigned long length;
};
--- a/dom/webidl/FileReaderSync.webidl
+++ b/dom/webidl/FileReaderSync.webidl
@@ -5,18 +5,16 @@
*
* The origin of this IDL file is
* http://dev.w3.org/2006/webapi/FileAPI/
*
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
* liability, trademark and document use rules apply.
*/
-interface Blob;
-
[Constructor,
Exposed=Worker]
interface FileReaderSync {
// Synchronously return strings
[Throws]
ArrayBuffer readAsArrayBuffer(Blob blob);
--- a/dom/webidl/HTMLCanvasElement.webidl
+++ b/dom/webidl/HTMLCanvasElement.webidl
@@ -5,17 +5,16 @@
*
* The origin of this IDL file is
* http://www.whatwg.org/specs/web-apps/current-work/#the-canvas-element
* © Copyright 2004-2011 Apple Computer, Inc., Mozilla Foundation, and
* Opera Software ASA. You are granted a license to use, reproduce
* and create derivative works of this document.
*/
-interface Blob;
interface nsIInputStreamCallback;
interface nsISupports;
interface Variant;
interface HTMLCanvasElement : HTMLElement {
[Pure, SetterThrows]
attribute unsigned long width;
[Pure, SetterThrows]
--- a/dom/webidl/XMLHttpRequest.webidl
+++ b/dom/webidl/XMLHttpRequest.webidl
@@ -5,17 +5,16 @@
*
* The origin of this IDL file is
* www.w3.org/TR/2012/WD-XMLHttpRequest-20120117/
*
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
* liability, trademark and document use rules apply.
*/
-interface Blob;
interface InputStream;
interface MozChannel;
interface IID;
enum XMLHttpRequestResponseType {
"",
"arraybuffer",
"blob",
deleted file mode 100644
--- a/dom/workers/File.cpp
+++ /dev/null
@@ -1,503 +0,0 @@
-/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
-/* vim: set ts=2 et sw=2 tw=80: */
-/* 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 "File.h"
-
-#include "nsDOMFile.h"
-#include "nsDOMBlobBuilder.h"
-#include "nsError.h"
-
-#include "jsapi.h"
-#include "jsfriendapi.h"
-#include "nsCOMPtr.h"
-#include "nsJSUtils.h"
-#include "nsString.h"
-
-#include "mozilla/dom/Exceptions.h"
-#include "WorkerInlines.h"
-#include "WorkerPrivate.h"
-
-USING_WORKERS_NAMESPACE
-using mozilla::dom::Throw;
-
-namespace {
-
-class Blob
-{
- // Blob should never be instantiated.
- Blob();
- ~Blob();
-
- static const JSClass sClass;
- static const JSPropertySpec sProperties[];
- static const JSFunctionSpec sFunctions[];
-
-public:
- static JSObject*
- InitClass(JSContext* aCx, JS::Handle<JSObject*> aObj)
- {
- return JS_InitClass(aCx, aObj, JS::NullPtr(), &sClass, Construct, 0,
- sProperties, sFunctions, nullptr, nullptr);
- }
-
- static JSObject*
- Create(JSContext* aCx, nsIDOMBlob* aBlob)
- {
- MOZ_ASSERT(SameCOMIdentity(static_cast<nsISupports*>(aBlob), aBlob));
-
- JSObject* obj = JS_NewObject(aCx, &sClass, JS::NullPtr(), JS::NullPtr());
- if (obj) {
- JS_SetPrivate(obj, aBlob);
- NS_ADDREF(aBlob);
- }
- return obj;
- }
-
- static nsIDOMBlob*
- GetPrivate(JSObject* aObj);
-
-private:
- static nsIDOMBlob*
- GetInstancePrivate(JSContext* aCx, JS::Handle<JSObject*> aObj, const char* aFunctionName)
- {
- nsIDOMBlob* blob = GetPrivate(aObj);
- if (blob) {
- return blob;
- }
-
- JS_ReportErrorNumber(aCx, js_GetErrorMessage, nullptr,
- JSMSG_INCOMPATIBLE_PROTO, sClass.name, aFunctionName,
- JS_GetClass(aObj)->name);
- return nullptr;
- }
-
- static nsIDOMBlob*
- Unwrap(JSContext* aCx, JSObject* aObj)
- {
- return GetPrivate(aObj);
- }
-
- static bool
- Construct(JSContext* aCx, unsigned aArgc, jsval* aVp)
- {
- JS::CallArgs args = CallArgsFromVp(aArgc, aVp);
-
- nsRefPtr<DOMMultipartFileImpl> fileImpl = new DOMMultipartFileImpl();
- nsRefPtr<mozilla::dom::DOMFile> file = new mozilla::dom::DOMFile(fileImpl);
-
- nsresult rv = fileImpl->InitBlob(aCx, args.length(), args.array(), Unwrap);
- if (NS_FAILED(rv)) {
- return Throw(aCx, rv);
- }
-
- JSObject* obj = file::CreateBlob(aCx, file);
- if (!obj) {
- return false;
- }
-
- args.rval().setObject(*obj);
- return true;
- }
-
- static void
- Finalize(JSFreeOp* aFop, JSObject* aObj)
- {
- MOZ_ASSERT(JS_GetClass(aObj) == &sClass);
-
- nsIDOMBlob* blob = GetPrivate(aObj);
- NS_IF_RELEASE(blob);
- }
-
- static bool
- IsBlob(JS::Handle<JS::Value> v)
- {
- return v.isObject() && GetPrivate(&v.toObject()) != nullptr;
- }
-
- static bool
- GetSizeImpl(JSContext* aCx, JS::CallArgs aArgs)
- {
- JS::Rooted<JSObject*> obj(aCx, &aArgs.thisv().toObject());
- nsIDOMBlob* blob = GetInstancePrivate(aCx, obj, "size");
- MOZ_ASSERT(blob);
-
- uint64_t size;
- if (NS_FAILED(blob->GetSize(&size))) {
- return Throw(aCx, NS_ERROR_DOM_FILE_NOT_READABLE_ERR);
- }
-
- aArgs.rval().setNumber(double(size));
- return true;
- }
-
- static bool
- GetSize(JSContext* aCx, unsigned aArgc, JS::Value* aVp)
- {
- JS::CallArgs args = JS::CallArgsFromVp(aArgc, aVp);
- return JS::CallNonGenericMethod<IsBlob, GetSizeImpl>(aCx, args);
- }
-
- static bool
- GetTypeImpl(JSContext* aCx, JS::CallArgs aArgs)
- {
- JS::Rooted<JSObject*> obj(aCx, &aArgs.thisv().toObject());
- nsIDOMBlob* blob = GetInstancePrivate(aCx, obj, "type");
- MOZ_ASSERT(blob);
-
- nsString type;
- if (NS_FAILED(blob->GetType(type))) {
- return Throw(aCx, NS_ERROR_DOM_FILE_NOT_READABLE_ERR);
- }
-
- JSString* jsType = JS_NewUCStringCopyN(aCx, type.get(), type.Length());
- if (!jsType) {
- return false;
- }
-
- aArgs.rval().setString(jsType);
- return true;
- }
-
- static bool
- GetType(JSContext* aCx, unsigned aArgc, JS::Value* aVp)
- {
- JS::CallArgs args = JS::CallArgsFromVp(aArgc, aVp);
- return JS::CallNonGenericMethod<IsBlob, GetTypeImpl>(aCx, args);
- }
-
- static bool
- Slice(JSContext* aCx, unsigned aArgc, jsval* aVp)
- {
- JS::CallArgs args = JS::CallArgsFromVp(aArgc, aVp);
-
- JS::Rooted<JSObject*> obj(aCx, args.thisv().toObjectOrNull());
- if (!obj) {
- return false;
- }
-
- nsIDOMBlob* blob = GetInstancePrivate(aCx, obj, "slice");
- if (!blob) {
- return false;
- }
-
- double start = 0, end = 0;
- JS::Rooted<JSString*> jsContentType(aCx, JS_GetEmptyString(JS_GetRuntime(aCx)));
- if (!JS_ConvertArguments(aCx, args, "/IIS", &start,
- &end, jsContentType.address())) {
- return false;
- }
-
- nsAutoJSString contentType;
- if (!contentType.init(aCx, jsContentType)) {
- return false;
- }
-
- uint8_t optionalArgc = aArgc;
- nsCOMPtr<nsIDOMBlob> rtnBlob;
- if (NS_FAILED(blob->Slice(static_cast<uint64_t>(start),
- static_cast<uint64_t>(end),
- contentType, optionalArgc,
- getter_AddRefs(rtnBlob)))) {
- return Throw(aCx, NS_ERROR_DOM_FILE_NOT_READABLE_ERR);
- }
-
- JSObject* rtnObj = file::CreateBlob(aCx, rtnBlob);
- if (!rtnObj) {
- return false;
- }
-
- args.rval().setObject(*rtnObj);
- return true;
- }
-};
-
-const JSClass Blob::sClass = {
- "Blob",
- JSCLASS_HAS_PRIVATE,
- JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
- JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, Finalize
-};
-
-const JSPropertySpec Blob::sProperties[] = {
- JS_PSGS("size", GetSize, GetterOnlyJSNative, JSPROP_ENUMERATE),
- JS_PSGS("type", GetType, GetterOnlyJSNative, JSPROP_ENUMERATE),
- JS_PS_END
-};
-
-const JSFunctionSpec Blob::sFunctions[] = {
- JS_FN("slice", Slice, 1, JSPROP_ENUMERATE),
- JS_FS_END
-};
-
-class File : public Blob
-{
- // File should never be instantiated.
- File();
- ~File();
-
- static const JSClass sClass;
- static const JSPropertySpec sProperties[];
-
-public:
- static JSObject*
- InitClass(JSContext* aCx, JS::Handle<JSObject*> aObj, JS::Handle<JSObject*> aParentProto)
- {
- return JS_InitClass(aCx, aObj, aParentProto, &sClass, Construct, 0,
- sProperties, nullptr, nullptr, nullptr);
- }
-
- static JSObject*
- Create(JSContext* aCx, nsIDOMFile* aFile)
- {
- MOZ_ASSERT(SameCOMIdentity(static_cast<nsISupports*>(aFile), aFile));
-
- JSObject* obj = JS_NewObject(aCx, &sClass, JS::NullPtr(), JS::NullPtr());
- if (obj) {
- JS_SetPrivate(obj, aFile);
- NS_ADDREF(aFile);
- }
- return obj;
- }
-
- static nsIDOMFile*
- GetPrivate(JSObject* aObj)
- {
- if (aObj) {
- const JSClass* classPtr = JS_GetClass(aObj);
- if (classPtr == &sClass) {
- nsISupports* priv = static_cast<nsISupports*>(JS_GetPrivate(aObj));
- nsCOMPtr<nsIDOMFile> file = do_QueryInterface(priv);
- MOZ_ASSERT_IF(priv, file);
- return file;
- }
- }
- return nullptr;
- }
-
- static const JSClass*
- Class()
- {
- return &sClass;
- }
-
-private:
- static nsIDOMFile*
- GetInstancePrivate(JSContext* aCx, JS::Handle<JSObject*> aObj, const char* aFunctionName)
- {
- nsIDOMFile* file = GetPrivate(aObj);
- if (file) {
- return file;
- }
-
- JS_ReportErrorNumber(aCx, js_GetErrorMessage, nullptr,
- JSMSG_INCOMPATIBLE_PROTO, sClass.name, aFunctionName,
- JS_GetClass(aObj)->name);
- return nullptr;
- }
-
- static bool
- Construct(JSContext* aCx, unsigned aArgc, jsval* aVp)
- {
- JS_ReportErrorNumber(aCx, js_GetErrorMessage, nullptr,
- JSMSG_WRONG_CONSTRUCTOR,
- sClass.name);
- return false;
- }
-
- static void
- Finalize(JSFreeOp* aFop, JSObject* aObj)
- {
- MOZ_ASSERT(JS_GetClass(aObj) == &sClass);
-
- nsIDOMFile* file = GetPrivate(aObj);
- NS_IF_RELEASE(file);
- }
-
- static bool
- IsFile(JS::Handle<JS::Value> v)
- {
- return v.isObject() && GetPrivate(&v.toObject()) != nullptr;
- }
-
- static bool
- GetMozFullPathImpl(JSContext* aCx, JS::CallArgs aArgs)
- {
- JS::Rooted<JSObject*> obj(aCx, &aArgs.thisv().toObject());
- nsIDOMFile* file = GetInstancePrivate(aCx, obj, "mozFullPath");
- MOZ_ASSERT(file);
-
- nsString fullPath;
-
- if (GetWorkerPrivateFromContext(aCx)->UsesSystemPrincipal() &&
- NS_FAILED(file->GetMozFullPathInternal(fullPath))) {
- return Throw(aCx, NS_ERROR_DOM_FILE_NOT_READABLE_ERR);
- }
-
- JSString* jsFullPath = JS_NewUCStringCopyN(aCx, fullPath.get(),
- fullPath.Length());
- if (!jsFullPath) {
- return false;
- }
-
- aArgs.rval().setString(jsFullPath);
- return true;
- }
-
- static bool
- GetMozFullPath(JSContext* aCx, unsigned aArgc, JS::Value* aVp)
- {
- JS::CallArgs args = JS::CallArgsFromVp(aArgc, aVp);
- return JS::CallNonGenericMethod<IsFile, GetMozFullPathImpl>(aCx, args);
- }
-
- static bool
- GetNameImpl(JSContext* aCx, JS::CallArgs aArgs)
- {
- JS::Rooted<JSObject*> obj(aCx, &aArgs.thisv().toObject());
- nsIDOMFile* file = GetInstancePrivate(aCx, obj, "name");
- MOZ_ASSERT(file);
-
- nsString name;
- if (NS_FAILED(file->GetName(name))) {
- name.Truncate();
- }
-
- JSString* jsName = JS_NewUCStringCopyN(aCx, name.get(), name.Length());
- if (!jsName) {
- return false;
- }
-
- aArgs.rval().setString(jsName);
- return true;
- }
-
- static bool
- GetName(JSContext* aCx, unsigned aArgc, JS::Value* aVp)
- {
- JS::CallArgs args = JS::CallArgsFromVp(aArgc, aVp);
- return JS::CallNonGenericMethod<IsFile, GetNameImpl>(aCx, args);
- }
-
- static bool
- GetPathImpl(JSContext* aCx, JS::CallArgs aArgs)
- {
- JS::Rooted<JSObject*> obj(aCx, &aArgs.thisv().toObject());
- nsIDOMFile* file = GetInstancePrivate(aCx, obj, "path");
- MOZ_ASSERT(file);
-
- nsString path;
- if (NS_FAILED(file->GetPath(path))) {
- path.Truncate();
- }
-
- JSString* jsPath = JS_NewUCStringCopyN(aCx, path.get(), path.Length());
- if (!jsPath) {
- return false;
- }
-
- aArgs.rval().setString(jsPath);
- return true;
- }
-
- static bool
- GetPath(JSContext* aCx, unsigned aArgc, JS::Value* aVp)
- {
- JS::CallArgs args = JS::CallArgsFromVp(aArgc, aVp);
- return JS::CallNonGenericMethod<IsFile, GetPathImpl>(aCx, args);
- }
-
- static bool
- GetLastModifiedDateImpl(JSContext* aCx, JS::CallArgs aArgs)
- {
- JS::Rooted<JSObject*> obj(aCx, &aArgs.thisv().toObject());
- nsIDOMFile* file = GetInstancePrivate(aCx, obj, "lastModifiedDate");
- MOZ_ASSERT(file);
-
- if (NS_FAILED(file->GetLastModifiedDate(aCx, aArgs.rval()))) {
- return false;
- }
- return true;
- }
-
- static bool
- GetLastModifiedDate(JSContext* aCx, unsigned aArgc, JS::Value* aVp)
- {
- JS::CallArgs args = JS::CallArgsFromVp(aArgc, aVp);
- return JS::CallNonGenericMethod<IsFile, GetLastModifiedDateImpl>(aCx, args);
- }
-};
-
-const JSClass File::sClass = {
- "File",
- JSCLASS_HAS_PRIVATE,
- JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
- JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, Finalize
-};
-
-const JSPropertySpec File::sProperties[] = {
- JS_PSGS("name", GetName, GetterOnlyJSNative, JSPROP_ENUMERATE),
- JS_PSGS("path", GetPath, GetterOnlyJSNative, JSPROP_ENUMERATE),
- JS_PSGS("lastModifiedDate", GetLastModifiedDate, GetterOnlyJSNative,
- JSPROP_ENUMERATE),
- JS_PSGS("mozFullPath", GetMozFullPath, GetterOnlyJSNative, JSPROP_ENUMERATE),
- JS_PS_END
-};
-
-nsIDOMBlob*
-Blob::GetPrivate(JSObject* aObj)
-{
- if (aObj) {
- const JSClass* classPtr = JS_GetClass(aObj);
- if (classPtr == &sClass || classPtr == File::Class()) {
- nsISupports* priv = static_cast<nsISupports*>(JS_GetPrivate(aObj));
- nsCOMPtr<nsIDOMBlob> blob = do_QueryInterface(priv);
- MOZ_ASSERT_IF(priv, blob);
- return blob;
- }
- }
- return nullptr;
-}
-
-} // anonymous namespace
-
-BEGIN_WORKERS_NAMESPACE
-
-namespace file {
-
-JSObject*
-CreateBlob(JSContext* aCx, nsIDOMBlob* aBlob)
-{
- return Blob::Create(aCx, aBlob);
-}
-
-bool
-InitClasses(JSContext* aCx, JS::Handle<JSObject*> aGlobal)
-{
- JS::Rooted<JSObject*> blobProto(aCx, Blob::InitClass(aCx, aGlobal));
- return blobProto && File::InitClass(aCx, aGlobal, blobProto);
-}
-
-nsIDOMBlob*
-GetDOMBlobFromJSObject(JSObject* aObj)
-{
- return Blob::GetPrivate(aObj);
-}
-
-JSObject*
-CreateFile(JSContext* aCx, nsIDOMFile* aFile)
-{
- return File::Create(aCx, aFile);
-}
-
-nsIDOMFile*
-GetDOMFileFromJSObject(JSObject* aObj)
-{
- return File::GetPrivate(aObj);
-}
-
-} // namespace file
-
-END_WORKERS_NAMESPACE
deleted file mode 100644
--- a/dom/workers/File.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
-/* vim: set ts=2 et sw=2 tw=80: */
-/* 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/. */
-
-#ifndef mozilla_dom_workers_file_h__
-#define mozilla_dom_workers_file_h__
-
-#include "Workers.h"
-
-class nsIDOMFile;
-class nsIDOMBlob;
-
-BEGIN_WORKERS_NAMESPACE
-
-namespace file {
-
-bool
-InitClasses(JSContext* aCx, JS::Handle<JSObject*> aGlobal);
-
-JSObject*
-CreateBlob(JSContext* aCx, nsIDOMBlob* aBlob);
-
-nsIDOMBlob*
-GetDOMBlobFromJSObject(JSObject* aObj);
-
-JSObject*
-CreateFile(JSContext* aCx, nsIDOMFile* aFile);
-
-nsIDOMFile*
-GetDOMFileFromJSObject(JSObject* aObj);
-
-} // namespace file
-
-END_WORKERS_NAMESPACE
-
-#endif /* mozilla_dom_workers_file_h__ */
--- a/dom/workers/FileReaderSync.cpp
+++ b/dom/workers/FileReaderSync.cpp
@@ -10,30 +10,30 @@
#include "mozilla/Base64.h"
#include "mozilla/dom/EncodingUtils.h"
#include "nsContentUtils.h"
#include "mozilla/dom/FileReaderSyncBinding.h"
#include "nsCExternalHandlerService.h"
#include "nsComponentManagerUtils.h"
#include "nsCOMPtr.h"
#include "nsDOMClassInfoID.h"
+#include "nsDOMFile.h"
#include "nsError.h"
-#include "nsIDOMFile.h"
#include "nsIConverterInputStream.h"
#include "nsIInputStream.h"
#include "nsISeekableStream.h"
#include "nsISupportsImpl.h"
#include "nsNetUtil.h"
#include "nsServiceManagerUtils.h"
-#include "File.h"
#include "RuntimeService.h"
USING_WORKERS_NAMESPACE
using namespace mozilla;
+using namespace mozilla::dom;
using mozilla::dom::Optional;
using mozilla::dom::GlobalObject;
// static
already_AddRefed<FileReaderSync>
FileReaderSync::Constructor(const GlobalObject& aGlobal, ErrorResult& aRv)
{
nsRefPtr<FileReaderSync> frs = new FileReaderSync();
@@ -45,28 +45,22 @@ JSObject*
FileReaderSync::WrapObject(JSContext* aCx)
{
return FileReaderSyncBinding_workers::Wrap(aCx, this);
}
void
FileReaderSync::ReadAsArrayBuffer(JSContext* aCx,
JS::Handle<JSObject*> aScopeObj,
- JS::Handle<JSObject*> aBlob,
+ DOMFile& aBlob,
JS::MutableHandle<JSObject*> aRetval,
ErrorResult& aRv)
{
- nsIDOMBlob* blob = file::GetDOMBlobFromJSObject(aBlob);
- if (!blob) {
- aRv.Throw(NS_ERROR_INVALID_ARG);
- return;
- }
-
uint64_t blobSize;
- nsresult rv = blob->GetSize(&blobSize);
+ nsresult rv = aBlob.GetSize(&blobSize);
if (NS_FAILED(rv)) {
aRv.Throw(rv);
return;
}
JS::Rooted<JSObject*> jsArrayBuffer(aCx, JS_NewArrayBuffer(aCx, blobSize));
if (!jsArrayBuffer) {
// XXXkhuey we need a way to indicate to the bindings that the call failed
@@ -78,17 +72,17 @@ FileReaderSync::ReadAsArrayBuffer(JSCont
uint32_t bufferLength = JS_GetArrayBufferByteLength(jsArrayBuffer);
uint8_t* arrayBuffer = JS_GetStableArrayBufferData(aCx, jsArrayBuffer);
if (!arrayBuffer) {
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
return;
}
nsCOMPtr<nsIInputStream> stream;
- rv = blob->GetInternalStream(getter_AddRefs(stream));
+ rv = aBlob.GetInternalStream(getter_AddRefs(stream));
if (NS_FAILED(rv)) {
aRv.Throw(rv);
return;
}
uint32_t numRead;
rv = stream->Read((char*)arrayBuffer, bufferLength, &numRead);
if (NS_FAILED(rv)) {
@@ -96,28 +90,22 @@ FileReaderSync::ReadAsArrayBuffer(JSCont
return;
}
NS_ASSERTION(numRead == bufferLength, "failed to read data");
aRetval.set(jsArrayBuffer);
}
void
-FileReaderSync::ReadAsBinaryString(JS::Handle<JSObject*> aBlob,
+FileReaderSync::ReadAsBinaryString(DOMFile& aBlob,
nsAString& aResult,
ErrorResult& aRv)
{
- nsIDOMBlob* blob = file::GetDOMBlobFromJSObject(aBlob);
- if (!blob) {
- aRv.Throw(NS_ERROR_INVALID_ARG);
- return;
- }
-
nsCOMPtr<nsIInputStream> stream;
- nsresult rv = blob->GetInternalStream(getter_AddRefs(stream));
+ nsresult rv = aBlob.GetInternalStream(getter_AddRefs(stream));
if (NS_FAILED(rv)) {
aRv.Throw(rv);
return;
}
uint32_t numRead;
do {
char readBuf[4096];
@@ -132,29 +120,23 @@ FileReaderSync::ReadAsBinaryString(JS::H
if (aResult.Length() - oldLength != numRead) {
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
return;
}
} while (numRead > 0);
}
void
-FileReaderSync::ReadAsText(JS::Handle<JSObject*> aBlob,
+FileReaderSync::ReadAsText(DOMFile& aBlob,
const Optional<nsAString>& aEncoding,
nsAString& aResult,
ErrorResult& aRv)
{
- nsIDOMBlob* blob = file::GetDOMBlobFromJSObject(aBlob);
- if (!blob) {
- aRv.Throw(NS_ERROR_INVALID_ARG);
- return;
- }
-
nsCOMPtr<nsIInputStream> stream;
- nsresult rv = blob->GetInternalStream(getter_AddRefs(stream));
+ nsresult rv = aBlob.GetInternalStream(getter_AddRefs(stream));
if (NS_FAILED(rv)) {
aRv.Throw(rv);
return;
}
nsAutoCString encoding;
unsigned char sniffBuf[3] = { 0, 0, 0 };
uint32_t numRead;
@@ -169,17 +151,17 @@ FileReaderSync::ReadAsText(JS::Handle<JS
// Standard, which the File API references.
if (!nsContentUtils::CheckForBOM(sniffBuf, numRead, encoding)) {
// BOM sniffing failed. Try the API argument.
if (!aEncoding.WasPassed() ||
!EncodingUtils::FindEncodingForLabel(aEncoding.Value(),
encoding)) {
// API argument failed. Try the type property of the blob.
nsAutoString type16;
- blob->GetType(type16);
+ aBlob.GetType(type16);
NS_ConvertUTF16toUTF8 type(type16);
nsAutoCString specifiedCharset;
bool haveCharset;
int32_t charsetStart, charsetEnd;
NS_ExtractCharsetFromContentType(type,
specifiedCharset,
&haveCharset,
&charsetStart,
@@ -208,47 +190,41 @@ FileReaderSync::ReadAsText(JS::Handle<JS
rv = ConvertStream(stream, encoding.get(), aResult);
if (NS_FAILED(rv)) {
aRv.Throw(rv);
return;
}
}
void
-FileReaderSync::ReadAsDataURL(JS::Handle<JSObject*> aBlob, nsAString& aResult,
+FileReaderSync::ReadAsDataURL(DOMFile& aBlob, nsAString& aResult,
ErrorResult& aRv)
{
- nsIDOMBlob* blob = file::GetDOMBlobFromJSObject(aBlob);
- if (!blob) {
- aRv.Throw(NS_ERROR_INVALID_ARG);
- return;
- }
-
nsAutoString scratchResult;
scratchResult.AssignLiteral("data:");
nsString contentType;
- blob->GetType(contentType);
+ aBlob.GetType(contentType);
if (contentType.IsEmpty()) {
scratchResult.AppendLiteral("application/octet-stream");
} else {
scratchResult.Append(contentType);
}
scratchResult.AppendLiteral(";base64,");
nsCOMPtr<nsIInputStream> stream;
- nsresult rv = blob->GetInternalStream(getter_AddRefs(stream));
+ nsresult rv = aBlob.GetInternalStream(getter_AddRefs(stream));
if (NS_FAILED(rv)) {
aRv.Throw(rv);
return;
}
uint64_t size;
- rv = blob->GetSize(&size);
+ rv = aBlob.GetSize(&size);
if (NS_FAILED(rv)) {
aRv.Throw(rv);
return;
}
nsCOMPtr<nsIInputStream> bufferedStream;
rv = NS_NewBufferedInputStream(getter_AddRefs(bufferedStream), stream, size);
if (NS_FAILED(rv)) {
--- a/dom/workers/FileReaderSync.h
+++ b/dom/workers/FileReaderSync.h
@@ -11,16 +11,17 @@
class nsIInputStream;
class nsIDOMBlob;
namespace mozilla {
class ErrorResult;
namespace dom {
+class DOMFile;
class GlobalObject;
template<typename> class Optional;
}
}
BEGIN_WORKERS_NAMESPACE
class FileReaderSync MOZ_FINAL
@@ -38,23 +39,19 @@ private:
public:
static already_AddRefed<FileReaderSync>
Constructor(const GlobalObject& aGlobal, ErrorResult& aRv);
JSObject* WrapObject(JSContext* aCx);
void ReadAsArrayBuffer(JSContext* aCx, JS::Handle<JSObject*> aScopeObj,
- JS::Handle<JSObject*> aBlob,
- JS::MutableHandle<JSObject*> aRetval,
+ DOMFile& aBlob, JS::MutableHandle<JSObject*> aRetval,
ErrorResult& aRv);
- void ReadAsBinaryString(JS::Handle<JSObject*> aBlob, nsAString& aResult,
- ErrorResult& aRv);
- void ReadAsText(JS::Handle<JSObject*> aBlob,
- const Optional<nsAString>& aEncoding,
+ void ReadAsBinaryString(DOMFile& aBlob, nsAString& aResult, ErrorResult& aRv);
+ void ReadAsText(DOMFile& aBlob, const Optional<nsAString>& aEncoding,
nsAString& aResult, ErrorResult& aRv);
- void ReadAsDataURL(JS::Handle<JSObject*> aBlob, nsAString& aResult,
- ErrorResult& aRv);
+ void ReadAsDataURL(DOMFile& aBlob, nsAString& aResult, ErrorResult& aRv);
};
END_WORKERS_NAMESPACE
#endif // mozilla_dom_workers_filereadersync_h__
--- a/dom/workers/RegisterBindings.cpp
+++ b/dom/workers/RegisterBindings.cpp
@@ -1,16 +1,15 @@
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
/* 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 "WorkerPrivate.h"
#include "ChromeWorkerScope.h"
-#include "File.h"
#include "RuntimeService.h"
#include "jsapi.h"
#include "js/OldDebugAPI.h"
#include "mozilla/dom/RegisterWorkerBindings.h"
#include "mozilla/OSFileConstants.h"
USING_WORKERS_NAMESPACE
@@ -26,19 +25,14 @@ WorkerPrivate::RegisterBindings(JSContex
if (IsChromeWorker()) {
if (!DefineChromeWorkerFunctions(aCx, aGlobal) ||
!DefineOSFileConstants(aCx, aGlobal)) {
return false;
}
}
- // Init other classes we care about.
- if (!file::InitClasses(aCx, aGlobal)) {
- return false;
- }
-
if (!JS_DefineProfilingFunctions(aCx, aGlobal)) {
return false;
}
return true;
}
--- a/dom/workers/URL.cpp
+++ b/dom/workers/URL.cpp
@@ -14,17 +14,16 @@
#include "mozilla/dom/URLBinding.h"
#include "mozilla/dom/URLSearchParams.h"
#include "nsGlobalWindow.h"
#include "nsHostObjectProtocolHandler.h"
#include "nsNetCID.h"
#include "nsServiceManagerUtils.h"
#include "nsThreadUtils.h"
-#include "File.h"
#include "WorkerPrivate.h"
#include "WorkerRunnable.h"
BEGIN_WORKERS_NAMESPACE
using mozilla::dom::GlobalObject;
class URLProxy MOZ_FINAL
{
@@ -843,50 +842,42 @@ URL::SetHash(const nsAString& aHash, Err
}
// static
void
URL::CreateObjectURL(const GlobalObject& aGlobal, JSObject* aBlob,
const mozilla::dom::objectURLOptions& aOptions,
nsString& aResult, mozilla::ErrorResult& aRv)
{
+ SetDOMStringToNull(aResult);
+
+ NS_NAMED_LITERAL_STRING(argStr, "Argument 1 of URL.createObjectURL");
+ NS_NAMED_LITERAL_STRING(blobStr, "MediaStream");
+ aRv.ThrowTypeError(MSG_DOES_NOT_IMPLEMENT_INTERFACE, &argStr, &blobStr);
+}
+
+// static
+void
+URL::CreateObjectURL(const GlobalObject& aGlobal, DOMFile& aBlob,
+ const mozilla::dom::objectURLOptions& aOptions,
+ nsString& aResult, mozilla::ErrorResult& aRv)
+{
JSContext* cx = aGlobal.Context();
WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(cx);
- nsCOMPtr<nsIDOMBlob> blob = file::GetDOMBlobFromJSObject(aBlob);
- if (!blob) {
- SetDOMStringToNull(aResult);
-
- NS_NAMED_LITERAL_STRING(argStr, "Argument 1 of URL.createObjectURL");
- NS_NAMED_LITERAL_STRING(blobStr, "Blob");
- aRv.ThrowTypeError(MSG_DOES_NOT_IMPLEMENT_INTERFACE, &argStr, &blobStr);
- return;
- }
-
- DOMFile* domBlob = static_cast<DOMFile*>(blob.get());
-
nsRefPtr<CreateURLRunnable> runnable =
- new CreateURLRunnable(workerPrivate, domBlob->Impl(), aOptions, aResult);
+ new CreateURLRunnable(workerPrivate, aBlob.Impl(), aOptions, aResult);
if (!runnable->Dispatch(cx)) {
JS_ReportPendingException(cx);
}
}
// static
void
-URL::CreateObjectURL(const GlobalObject& aGlobal, JSObject& aBlob,
- const mozilla::dom::objectURLOptions& aOptions,
- nsString& aResult, mozilla::ErrorResult& aRv)
-{
- return CreateObjectURL(aGlobal, &aBlob, aOptions, aResult, aRv);
-}
-
-// static
-void
URL::RevokeObjectURL(const GlobalObject& aGlobal, const nsAString& aUrl)
{
JSContext* cx = aGlobal.Context();
WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(cx);
nsRefPtr<RevokeURLRunnable> runnable =
new RevokeURLRunnable(workerPrivate, aUrl);
--- a/dom/workers/URL.h
+++ b/dom/workers/URL.h
@@ -12,16 +12,17 @@
#include "mozilla/ErrorResult.h"
#include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/dom/URLSearchParams.h"
class nsIPrincipal;
namespace mozilla {
namespace dom {
+class DOMFile;
struct objectURLOptions;
}
}
BEGIN_WORKERS_NAMESPACE
class URLProxy;
@@ -58,17 +59,17 @@ public:
static void
CreateObjectURL(const GlobalObject& aGlobal,
JSObject* aArg, const objectURLOptions& aOptions,
nsString& aResult, ErrorResult& aRv);
static void
CreateObjectURL(const GlobalObject& aGlobal,
- JSObject& aArg, const objectURLOptions& aOptions,
+ DOMFile& aArg, const objectURLOptions& aOptions,
nsString& aResult, ErrorResult& aRv);
static void
RevokeObjectURL(const GlobalObject& aGlobal, const nsAString& aUrl);
void GetHref(nsString& aHref, ErrorResult& aRv) const;
void SetHref(const nsAString& aHref, ErrorResult& aRv);
--- a/dom/workers/WorkerPrivate.cpp
+++ b/dom/workers/WorkerPrivate.cpp
@@ -35,16 +35,17 @@
#include "js/OldDebugAPI.h"
#include "js/MemoryMetrics.h"
#include "mozilla/Assertions.h"
#include "mozilla/Attributes.h"
#include "mozilla/ContentEvents.h"
#include "mozilla/EventDispatcher.h"
#include "mozilla/Likely.h"
#include "mozilla/dom/BindingUtils.h"
+#include "mozilla/dom/BlobBinding.h"
#include "mozilla/dom/ErrorEvent.h"
#include "mozilla/dom/ErrorEventBinding.h"
#include "mozilla/dom/Exceptions.h"
#include "mozilla/dom/FunctionBinding.h"
#include "mozilla/dom/ImageData.h"
#include "mozilla/dom/ImageDataBinding.h"
#include "mozilla/dom/MessageEvent.h"
#include "mozilla/dom/MessageEventBinding.h"
@@ -69,17 +70,16 @@
#ifdef ANDROID
#include <android/log.h>
#endif
#ifdef DEBUG
#include "nsThreadManager.h"
#endif
-#include "File.h"
#include "MessagePort.h"
#include "Navigator.h"
#include "Principal.h"
#include "RuntimeService.h"
#include "ScriptLoader.h"
#include "ServiceWorkerManager.h"
#include "SharedWorker.h"
#include "WorkerFeature.h"
@@ -294,44 +294,18 @@ LogErrorToConsole(const nsAString& aMess
struct WorkerStructuredCloneCallbacks
{
static JSObject*
Read(JSContext* aCx, JSStructuredCloneReader* aReader, uint32_t aTag,
uint32_t aData, void* aClosure)
{
JS::Rooted<JSObject*> result(aCx);
- // See if object is a nsIDOMFile pointer.
- if (aTag == DOMWORKER_SCTAG_FILE) {
- MOZ_ASSERT(!aData);
-
- DOMFileImpl* fileImpl;
- if (JS_ReadBytes(aReader, &fileImpl, sizeof(fileImpl))) {
- MOZ_ASSERT(fileImpl);
-
-#ifdef DEBUG
- {
- // File should not be mutable.
- bool isMutable;
- NS_ASSERTION(NS_SUCCEEDED(fileImpl->GetMutable(&isMutable)) &&
- !isMutable,
- "Only immutable file should be passed to worker");
- }
-#endif
-
- {
- // New scope to protect |result| from a moving GC during ~nsRefPtr.
- nsRefPtr<DOMFile> file = new DOMFile(fileImpl);
- result = file::CreateFile(aCx, file);
- }
- return result;
- }
- }
// See if object is a nsIDOMBlob pointer.
- else if (aTag == DOMWORKER_SCTAG_BLOB) {
+ if (aTag == DOMWORKER_SCTAG_BLOB) {
MOZ_ASSERT(!aData);
DOMFileImpl* blobImpl;
if (JS_ReadBytes(aReader, &blobImpl, sizeof(blobImpl))) {
MOZ_ASSERT(blobImpl);
#ifdef DEBUG
{
@@ -340,19 +314,23 @@ struct WorkerStructuredCloneCallbacks
NS_ASSERTION(NS_SUCCEEDED(blobImpl->GetMutable(&isMutable)) &&
!isMutable,
"Only immutable blob should be passed to worker");
}
#endif
{
// New scope to protect |result| from a moving GC during ~nsRefPtr.
- nsRefPtr<DOMFile> blob = new DOMFile(blobImpl);
- result = file::CreateBlob(aCx, blob);
+ nsRefPtr<DOMFile> blob = new DOMFile(nullptr, blobImpl);
+ JS::Rooted<JS::Value> val(aCx);
+ if (WrapNewBindingObject(aCx, blob, &val)) {
+ result = val.toObjectOrNull();
+ }
}
+
return result;
}
}
// See if the object is an ImageData.
else if (aTag == SCTAG_DOM_IMAGEDATA) {
MOZ_ASSERT(!aData);
return ReadStructuredCloneImageData(aCx, aReader);
}
@@ -366,34 +344,21 @@ struct WorkerStructuredCloneCallbacks
JS::Handle<JSObject*> aObj, void* aClosure)
{
NS_ASSERTION(aClosure, "Null pointer!");
// We'll stash any nsISupports pointers that need to be AddRef'd here.
nsTArray<nsCOMPtr<nsISupports> >* clonedObjects =
static_cast<nsTArray<nsCOMPtr<nsISupports> >*>(aClosure);
- // See if this is a File object.
+ // See if this is a Blob/File object.
{
- nsIDOMFile* file = file::GetDOMFileFromJSObject(aObj);
- if (file) {
- DOMFileImpl* fileImpl = static_cast<DOMFile*>(file)->Impl();
- if (JS_WriteUint32Pair(aWriter, DOMWORKER_SCTAG_FILE, 0) &&
- JS_WriteBytes(aWriter, &fileImpl, sizeof(fileImpl))) {
- clonedObjects->AppendElement(fileImpl);
- return true;
- }
- }
- }
-
- // See if this is a Blob object.
- {
- nsIDOMBlob* blob = file::GetDOMBlobFromJSObject(aObj);
- if (blob) {
- DOMFileImpl* blobImpl = static_cast<DOMFile*>(blob)->Impl();
+ DOMFile* blob = nullptr;
+ if (NS_SUCCEEDED(UNWRAP_OBJECT(Blob, aObj, blob))) {
+ DOMFileImpl* blobImpl = blob->Impl();
if (blobImpl && NS_SUCCEEDED(blobImpl->SetMutable(false)) &&
JS_WriteUint32Pair(aWriter, DOMWORKER_SCTAG_BLOB, 0) &&
JS_WriteBytes(aWriter, &blobImpl, sizeof(blobImpl))) {
clonedObjects->AppendElement(blobImpl);
return true;
}
}
}
@@ -429,82 +394,48 @@ JSStructuredCloneCallbacks gWorkerStruct
struct MainThreadWorkerStructuredCloneCallbacks
{
static JSObject*
Read(JSContext* aCx, JSStructuredCloneReader* aReader, uint32_t aTag,
uint32_t aData, void* aClosure)
{
AssertIsOnMainThread();
- // See if object is a nsIDOMFile pointer.
- if (aTag == DOMWORKER_SCTAG_FILE) {
- MOZ_ASSERT(!aData);
-
- DOMFileImpl* fileImpl;
- if (JS_ReadBytes(aReader, &fileImpl, sizeof(fileImpl))) {
- MOZ_ASSERT(fileImpl);
-
-#ifdef DEBUG
- {
- // File should not be mutable.
- bool isMutable;
- NS_ASSERTION(NS_SUCCEEDED(fileImpl->GetMutable(&isMutable)) &&
- !isMutable,
- "Only immutable file should be passed to worker");
- }
-#endif
-
- nsCOMPtr<nsIDOMFile> file = new DOMFile(fileImpl);
-
- // nsIDOMFiles should be threadsafe, thus we will use the same instance
- // on the main thread.
- JS::Rooted<JS::Value> wrappedFile(aCx);
- nsresult rv = nsContentUtils::WrapNative(aCx, file,
- &NS_GET_IID(nsIDOMFile),
- &wrappedFile);
- if (NS_FAILED(rv)) {
- Error(aCx, nsIDOMDOMException::DATA_CLONE_ERR);
- return nullptr;
- }
-
- return &wrappedFile.toObject();
- }
- }
- // See if object is a nsIDOMBlob pointer.
- else if (aTag == DOMWORKER_SCTAG_BLOB) {
+ // See if object is a Blob/File pointer.
+ if (aTag == DOMWORKER_SCTAG_BLOB) {
MOZ_ASSERT(!aData);
DOMFileImpl* blobImpl;
if (JS_ReadBytes(aReader, &blobImpl, sizeof(blobImpl))) {
MOZ_ASSERT(blobImpl);
#ifdef DEBUG
{
// Blob should not be mutable.
bool isMutable;
NS_ASSERTION(NS_SUCCEEDED(blobImpl->GetMutable(&isMutable)) &&
!isMutable,
"Only immutable blob should be passed to worker");
}
#endif
- nsCOMPtr<nsIDOMBlob> blob = new DOMFile(blobImpl);
-
- // nsIDOMBlobs should be threadsafe, thus we will use the same instance
- // on the main thread.
- JS::Rooted<JS::Value> wrappedBlob(aCx);
- nsresult rv = nsContentUtils::WrapNative(aCx, blob,
- &NS_GET_IID(nsIDOMBlob),
- &wrappedBlob);
- if (NS_FAILED(rv)) {
- Error(aCx, nsIDOMDOMException::DATA_CLONE_ERR);
- return nullptr;
+ // nsRefPtr<DOMFile> needs to go out of scope before toObjectOrNull() is
+ // called because the static analysis thinks dereferencing XPCOM objects
+ // can GC (because in some cases it can!), and a return statement with a
+ // JSObject* type means that JSObject* is on the stack as a raw pointer
+ // while destructors are running.
+ JS::Rooted<JS::Value> val(aCx);
+ {
+ nsRefPtr<DOMFile> blob = new DOMFile(nullptr, blobImpl);
+ if (!WrapNewBindingObject(aCx, blob, &val)) {
+ return nullptr;
+ }
}
- return &wrappedBlob.toObject();
+ return &val.toObject();
}
}
JS_ClearPendingException(aCx);
return NS_DOMReadStructuredClone(aCx, aReader, aTag, aData, nullptr);
}
static bool
@@ -514,63 +445,28 @@ struct MainThreadWorkerStructuredCloneCa
AssertIsOnMainThread();
NS_ASSERTION(aClosure, "Null pointer!");
// We'll stash any nsISupports pointers that need to be AddRef'd here.
nsTArray<nsCOMPtr<nsISupports> >* clonedObjects =
static_cast<nsTArray<nsCOMPtr<nsISupports> >*>(aClosure);
- // See if this is a wrapped native.
- nsCOMPtr<nsIXPConnectWrappedNative> wrappedNative;
- nsContentUtils::XPConnect()->
- GetWrappedNativeOfJSObject(aCx, aObj, getter_AddRefs(wrappedNative));
-
- if (wrappedNative) {
- // Get the raw nsISupports out of it.
- nsISupports* wrappedObject = wrappedNative->Native();
- NS_ASSERTION(wrappedObject, "Null pointer?!");
-
- // See if the wrapped native is a nsIDOMFile.
- nsCOMPtr<nsIDOMFile> file = do_QueryInterface(wrappedObject);
- if (file) {
- nsRefPtr<DOMFileImpl> fileImpl =
- static_cast<DOMFile*>(file.get())->Impl();
-
- if (fileImpl->IsCCed()) {
- NS_WARNING("Cycle collected file objects are not supported!");
- } else {
- if (NS_SUCCEEDED(fileImpl->SetMutable(false))) {
- DOMFileImpl* fileImplPtr = fileImpl;
- if (JS_WriteUint32Pair(aWriter, DOMWORKER_SCTAG_FILE, 0) &&
- JS_WriteBytes(aWriter, &fileImplPtr, sizeof(fileImplPtr))) {
- clonedObjects->AppendElement(fileImpl);
- return true;
- }
- }
- }
- }
-
- // See if the wrapped native is a nsIDOMBlob.
- nsCOMPtr<nsIDOMBlob> blob = do_Quer