mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge m-c to inbound.
This commit is contained in:
commit
0744ad5c35
@ -208,3 +208,14 @@
|
|||||||
fun:_ZN2js3ion5Range6updateEPKS1_
|
fun:_ZN2js3ion5Range6updateEPKS1_
|
||||||
...
|
...
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
Bug 803386
|
||||||
|
Memcheck:Free
|
||||||
|
fun:_ZdlPv
|
||||||
|
fun:_ZN16SkMallocPixelRefD0Ev
|
||||||
|
fun:_ZNK8SkRefCnt16internal_disposeEv
|
||||||
|
fun:_ZN8SkBitmap10freePixelsEv
|
||||||
|
fun:_ZN8SkBitmapD1Ev
|
||||||
|
fun:_ZN7mozilla3gfx5ScaleEPhiiiS1_iiiNS0_13SurfaceFormatE
|
||||||
|
...
|
||||||
|
}
|
||||||
|
@ -54,14 +54,14 @@ public:
|
|||||||
|
|
||||||
void
|
void
|
||||||
SetLazyData(const nsAString& aName, const nsAString& aContentType,
|
SetLazyData(const nsAString& aName, const nsAString& aContentType,
|
||||||
uint64_t aLength)
|
uint64_t aLength, uint64_t aLastModifiedDate)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(aLength, "must have length");
|
NS_ASSERTION(aLength, "must have length");
|
||||||
|
|
||||||
mName = aName;
|
mName = aName;
|
||||||
mContentType = aContentType;
|
mContentType = aContentType;
|
||||||
mLength = aLength;
|
mLength = aLength;
|
||||||
|
mLastModificationDate = aLastModifiedDate;
|
||||||
mIsFile = !aName.IsVoid();
|
mIsFile = !aName.IsVoid();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,11 +70,25 @@ public:
|
|||||||
return mLength == UINT64_MAX;
|
return mLength == UINT64_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsDateUnknown() const
|
||||||
|
{
|
||||||
|
return mIsFile && mLastModificationDate == UINT64_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
nsDOMFileBase(const nsAString& aName, const nsAString& aContentType,
|
||||||
|
uint64_t aLength, uint64_t aLastModifiedDate)
|
||||||
|
: mIsFile(true), mImmutable(false), mContentType(aContentType),
|
||||||
|
mName(aName), mStart(0), mLength(aLength), mLastModificationDate(aLastModifiedDate)
|
||||||
|
{
|
||||||
|
// Ensure non-null mContentType by default
|
||||||
|
mContentType.SetIsVoid(false);
|
||||||
|
}
|
||||||
|
|
||||||
nsDOMFileBase(const nsAString& aName, const nsAString& aContentType,
|
nsDOMFileBase(const nsAString& aName, const nsAString& aContentType,
|
||||||
uint64_t aLength)
|
uint64_t aLength)
|
||||||
: mIsFile(true), mImmutable(false), mContentType(aContentType),
|
: mIsFile(true), mImmutable(false), mContentType(aContentType),
|
||||||
mName(aName), mStart(0), mLength(aLength)
|
mName(aName), mStart(0), mLength(aLength), mLastModificationDate(UINT64_MAX)
|
||||||
{
|
{
|
||||||
// Ensure non-null mContentType by default
|
// Ensure non-null mContentType by default
|
||||||
mContentType.SetIsVoid(false);
|
mContentType.SetIsVoid(false);
|
||||||
@ -82,7 +96,7 @@ protected:
|
|||||||
|
|
||||||
nsDOMFileBase(const nsAString& aContentType, uint64_t aLength)
|
nsDOMFileBase(const nsAString& aContentType, uint64_t aLength)
|
||||||
: mIsFile(false), mImmutable(false), mContentType(aContentType),
|
: mIsFile(false), mImmutable(false), mContentType(aContentType),
|
||||||
mStart(0), mLength(aLength)
|
mStart(0), mLength(aLength), mLastModificationDate(UINT64_MAX)
|
||||||
{
|
{
|
||||||
// Ensure non-null mContentType by default
|
// Ensure non-null mContentType by default
|
||||||
mContentType.SetIsVoid(false);
|
mContentType.SetIsVoid(false);
|
||||||
@ -91,7 +105,7 @@ protected:
|
|||||||
nsDOMFileBase(const nsAString& aContentType, uint64_t aStart,
|
nsDOMFileBase(const nsAString& aContentType, uint64_t aStart,
|
||||||
uint64_t aLength)
|
uint64_t aLength)
|
||||||
: mIsFile(false), mImmutable(false), mContentType(aContentType),
|
: mIsFile(false), mImmutable(false), mContentType(aContentType),
|
||||||
mStart(aStart), mLength(aLength)
|
mStart(aStart), mLength(aLength), mLastModificationDate(UINT64_MAX)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(aLength != UINT64_MAX,
|
NS_ASSERTION(aLength != UINT64_MAX,
|
||||||
"Must know length when creating slice");
|
"Must know length when creating slice");
|
||||||
@ -127,12 +141,15 @@ protected:
|
|||||||
|
|
||||||
bool mIsFile;
|
bool mIsFile;
|
||||||
bool mImmutable;
|
bool mImmutable;
|
||||||
|
|
||||||
nsString mContentType;
|
nsString mContentType;
|
||||||
nsString mName;
|
nsString mName;
|
||||||
|
|
||||||
uint64_t mStart;
|
uint64_t mStart;
|
||||||
uint64_t mLength;
|
uint64_t mLength;
|
||||||
|
|
||||||
|
uint64_t mLastModificationDate;
|
||||||
|
|
||||||
// Protected by IndexedDatabaseManager::FileMutex()
|
// Protected by IndexedDatabaseManager::FileMutex()
|
||||||
nsTArray<nsRefPtr<FileInfo> > mFileInfos;
|
nsTArray<nsRefPtr<FileInfo> > mFileInfos;
|
||||||
};
|
};
|
||||||
@ -140,6 +157,11 @@ protected:
|
|||||||
class nsDOMFile : public nsDOMFileBase
|
class nsDOMFile : public nsDOMFileBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
nsDOMFile(const nsAString& aName, const nsAString& aContentType,
|
||||||
|
uint64_t aLength, uint64_t aLastModifiedDate)
|
||||||
|
: nsDOMFileBase(aName, aContentType, aLength, aLastModifiedDate)
|
||||||
|
{ }
|
||||||
|
|
||||||
nsDOMFile(const nsAString& aName, const nsAString& aContentType,
|
nsDOMFile(const nsAString& aName, const nsAString& aContentType,
|
||||||
uint64_t aLength)
|
uint64_t aLength)
|
||||||
: nsDOMFileBase(aName, aContentType, aLength)
|
: nsDOMFileBase(aName, aContentType, aLength)
|
||||||
@ -183,7 +205,7 @@ class nsDOMFileFile : public nsDOMFile,
|
|||||||
public:
|
public:
|
||||||
// Create as a file
|
// Create as a file
|
||||||
nsDOMFileFile(nsIFile *aFile)
|
nsDOMFileFile(nsIFile *aFile)
|
||||||
: nsDOMFile(EmptyString(), EmptyString(), UINT64_MAX),
|
: nsDOMFile(EmptyString(), EmptyString(), UINT64_MAX, UINT64_MAX),
|
||||||
mFile(aFile), mWholeFile(true), mStoredFile(false)
|
mFile(aFile), mWholeFile(true), mStoredFile(false)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(mFile, "must have file");
|
NS_ASSERTION(mFile, "must have file");
|
||||||
@ -195,7 +217,15 @@ public:
|
|||||||
// Create as a file
|
// Create as a file
|
||||||
nsDOMFileFile(const nsAString& aName, const nsAString& aContentType,
|
nsDOMFileFile(const nsAString& aName, const nsAString& aContentType,
|
||||||
uint64_t aLength, nsIFile *aFile)
|
uint64_t aLength, nsIFile *aFile)
|
||||||
: nsDOMFile(aName, aContentType, aLength),
|
: nsDOMFile(aName, aContentType, aLength, UINT64_MAX),
|
||||||
|
mFile(aFile), mWholeFile(true), mStoredFile(false)
|
||||||
|
{
|
||||||
|
NS_ASSERTION(mFile, "must have file");
|
||||||
|
}
|
||||||
|
|
||||||
|
nsDOMFileFile(const nsAString& aName, const nsAString& aContentType,
|
||||||
|
uint64_t aLength, nsIFile *aFile, uint64_t aLastModificationDate)
|
||||||
|
: nsDOMFile(aName, aContentType, aLength, aLastModificationDate),
|
||||||
mFile(aFile), mWholeFile(true), mStoredFile(false)
|
mFile(aFile), mWholeFile(true), mStoredFile(false)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(mFile, "must have file");
|
NS_ASSERTION(mFile, "must have file");
|
||||||
@ -213,7 +243,7 @@ public:
|
|||||||
|
|
||||||
// Create as a file with custom name
|
// Create as a file with custom name
|
||||||
nsDOMFileFile(nsIFile *aFile, const nsAString& aName)
|
nsDOMFileFile(nsIFile *aFile, const nsAString& aName)
|
||||||
: nsDOMFile(aName, EmptyString(), UINT64_MAX),
|
: nsDOMFile(aName, EmptyString(), UINT64_MAX, UINT64_MAX),
|
||||||
mFile(aFile), mWholeFile(true), mStoredFile(false)
|
mFile(aFile), mWholeFile(true), mStoredFile(false)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(mFile, "must have file");
|
NS_ASSERTION(mFile, "must have file");
|
||||||
@ -225,7 +255,7 @@ public:
|
|||||||
nsDOMFileFile(const nsAString& aName, const nsAString& aContentType,
|
nsDOMFileFile(const nsAString& aName, const nsAString& aContentType,
|
||||||
uint64_t aLength, nsIFile* aFile,
|
uint64_t aLength, nsIFile* aFile,
|
||||||
FileInfo* aFileInfo)
|
FileInfo* aFileInfo)
|
||||||
: nsDOMFile(aName, aContentType, aLength),
|
: nsDOMFile(aName, aContentType, aLength, UINT64_MAX),
|
||||||
mFile(aFile), mWholeFile(true), mStoredFile(true)
|
mFile(aFile), mWholeFile(true), mStoredFile(true)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(mFile, "must have file");
|
NS_ASSERTION(mFile, "must have file");
|
||||||
@ -244,7 +274,7 @@ public:
|
|||||||
|
|
||||||
// Create as a file to be later initialized
|
// Create as a file to be later initialized
|
||||||
nsDOMFileFile()
|
nsDOMFileFile()
|
||||||
: nsDOMFile(EmptyString(), EmptyString(), UINT64_MAX),
|
: nsDOMFile(EmptyString(), EmptyString(), UINT64_MAX, UINT64_MAX),
|
||||||
mWholeFile(true), mStoredFile(false)
|
mWholeFile(true), mStoredFile(false)
|
||||||
{
|
{
|
||||||
// Lazily get the content type and size
|
// Lazily get the content type and size
|
||||||
@ -264,7 +294,8 @@ public:
|
|||||||
// Overrides
|
// Overrides
|
||||||
NS_IMETHOD GetSize(uint64_t* aSize);
|
NS_IMETHOD GetSize(uint64_t* aSize);
|
||||||
NS_IMETHOD GetType(nsAString& aType);
|
NS_IMETHOD GetType(nsAString& aType);
|
||||||
NS_IMETHOD GetLastModifiedDate(JSContext* cx, JS::Value *aLastModifiedDate);
|
NS_IMETHOD GetLastModifiedDate(JSContext* cx, JS::Value* aLastModifiedDate);
|
||||||
|
NS_IMETHOD GetMozLastModifiedDate(uint64_t* aLastModifiedDate);
|
||||||
NS_IMETHOD GetMozFullPathInternal(nsAString& aFullPath);
|
NS_IMETHOD GetMozFullPathInternal(nsAString& aFullPath);
|
||||||
NS_IMETHOD GetInternalStream(nsIInputStream**);
|
NS_IMETHOD GetInternalStream(nsIInputStream**);
|
||||||
|
|
||||||
@ -328,7 +359,7 @@ public:
|
|||||||
uint64_t aLength,
|
uint64_t aLength,
|
||||||
const nsAString& aName,
|
const nsAString& aName,
|
||||||
const nsAString& aContentType)
|
const nsAString& aContentType)
|
||||||
: nsDOMFile(aName, aContentType, aLength),
|
: nsDOMFile(aName, aContentType, aLength, UINT64_MAX),
|
||||||
mDataOwner(new DataOwner(aMemoryBuffer))
|
mDataOwner(new DataOwner(aMemoryBuffer))
|
||||||
{
|
{
|
||||||
NS_ASSERTION(mDataOwner && mDataOwner->mData, "must have data");
|
NS_ASSERTION(mDataOwner && mDataOwner->mData, "must have data");
|
||||||
|
@ -28,7 +28,7 @@ interface nsIURI;
|
|||||||
interface nsIPrincipal;
|
interface nsIPrincipal;
|
||||||
interface nsIDOMBlob;
|
interface nsIDOMBlob;
|
||||||
|
|
||||||
[scriptable, builtinclass, uuid(16e3f8d1-7f31-48cc-93f5-9c931a977cf6)]
|
[scriptable, builtinclass, uuid(52d22585-7737-460e-9731-c658df03304a)]
|
||||||
interface nsIDOMBlob : nsISupports
|
interface nsIDOMBlob : nsISupports
|
||||||
{
|
{
|
||||||
readonly attribute unsigned long long size;
|
readonly attribute unsigned long long size;
|
||||||
@ -73,4 +73,6 @@ interface nsIDOMFile : nsIDOMBlob
|
|||||||
|
|
||||||
// This performs no security checks!
|
// This performs no security checks!
|
||||||
[noscript] readonly attribute DOMString mozFullPathInternal;
|
[noscript] readonly attribute DOMString mozFullPathInternal;
|
||||||
|
|
||||||
|
[noscript] readonly attribute uint64_t mozLastModifiedDate;
|
||||||
};
|
};
|
||||||
|
@ -888,11 +888,15 @@ nsIContent::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
|
|||||||
// Event may need to be retargeted if this is the root of a native
|
// Event may need to be retargeted if this is the root of a native
|
||||||
// anonymous content subtree or event is dispatched somewhere inside XBL.
|
// anonymous content subtree or event is dispatched somewhere inside XBL.
|
||||||
if (isAnonForEvents) {
|
if (isAnonForEvents) {
|
||||||
|
#ifdef DEBUG
|
||||||
// If a DOM event is explicitly dispatched using node.dispatchEvent(), then
|
// If a DOM event is explicitly dispatched using node.dispatchEvent(), then
|
||||||
// all the events are allowed even in the native anonymous content..
|
// all the events are allowed even in the native anonymous content..
|
||||||
NS_ASSERTION(aVisitor.mEvent->eventStructType != NS_MUTATION_EVENT ||
|
nsCOMPtr<nsIContent> t = do_QueryInterface(aVisitor.mEvent->originalTarget);
|
||||||
|
NS_ASSERTION(!t || !t->ChromeOnlyAccess() ||
|
||||||
|
aVisitor.mEvent->eventStructType != NS_MUTATION_EVENT ||
|
||||||
aVisitor.mDOMEvent,
|
aVisitor.mDOMEvent,
|
||||||
"Mutation event dispatched in native anonymous content!?!");
|
"Mutation event dispatched in native anonymous content!?!");
|
||||||
|
#endif
|
||||||
aVisitor.mEventTargetAtParent = parent;
|
aVisitor.mEventTargetAtParent = parent;
|
||||||
} else if (parent && aVisitor.mOriginalTargetIsInAnon) {
|
} else if (parent && aVisitor.mOriginalTargetIsInAnon) {
|
||||||
nsCOMPtr<nsIContent> content(do_QueryInterface(aVisitor.mEvent->target));
|
nsCOMPtr<nsIContent> content(do_QueryInterface(aVisitor.mEvent->target));
|
||||||
|
@ -174,6 +174,14 @@ nsDOMFileBase::GetType(nsAString &aType)
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsDOMFileBase::GetMozLastModifiedDate(uint64_t* aLastModifiedDate)
|
||||||
|
{
|
||||||
|
NS_ASSERTION(mIsFile, "Should only be called on files");
|
||||||
|
*aLastModifiedDate = mLastModificationDate;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
// Makes sure that aStart and aEnd is less then or equal to aSize and greater
|
// Makes sure that aStart and aEnd is less then or equal to aSize and greater
|
||||||
// than 0
|
// than 0
|
||||||
static void
|
static void
|
||||||
@ -498,10 +506,20 @@ nsDOMFileFile::GetMozFullPathInternal(nsAString &aFilename)
|
|||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsDOMFileFile::GetLastModifiedDate(JSContext* cx, JS::Value *aLastModifiedDate)
|
nsDOMFileFile::GetLastModifiedDate(JSContext* cx, JS::Value* aLastModifiedDate)
|
||||||
{
|
{
|
||||||
|
NS_ASSERTION(mIsFile, "Should only be called on files");
|
||||||
|
|
||||||
PRTime msecs;
|
PRTime msecs;
|
||||||
mFile->GetLastModifiedTime(&msecs);
|
mFile->GetLastModifiedTime(&msecs);
|
||||||
|
if (IsDateUnknown()) {
|
||||||
|
nsresult rv = mFile->GetLastModifiedTime(&msecs);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
mLastModificationDate = msecs;
|
||||||
|
} else {
|
||||||
|
msecs = mLastModificationDate;
|
||||||
|
}
|
||||||
|
|
||||||
JSObject* date = JS_NewDateObjectMsec(cx, msecs);
|
JSObject* date = JS_NewDateObjectMsec(cx, msecs);
|
||||||
if (date) {
|
if (date) {
|
||||||
aLastModifiedDate->setObject(*date);
|
aLastModifiedDate->setObject(*date);
|
||||||
@ -562,6 +580,14 @@ nsDOMFileFile::GetType(nsAString &aType)
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsDOMFileFile::GetMozLastModifiedDate(uint64_t* aLastModifiedDate)
|
||||||
|
{
|
||||||
|
NS_ASSERTION(mIsFile, "Should only be called on files");
|
||||||
|
*aLastModifiedDate = mLastModificationDate;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
const uint32_t sFileStreamFlags =
|
const uint32_t sFileStreamFlags =
|
||||||
nsIFileInputStream::CLOSE_ON_EOF |
|
nsIFileInputStream::CLOSE_ON_EOF |
|
||||||
nsIFileInputStream::REOPEN_ON_REWIND |
|
nsIFileInputStream::REOPEN_ON_REWIND |
|
||||||
|
@ -10,14 +10,21 @@
|
|||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
|
||||||
|
// CHANGING THE ORDER/PLACEMENT OF EXISTING ENUM VALUES MAY BREAK INDEXEDDB.
|
||||||
|
// PROCEED WITH EXTREME CAUTION.
|
||||||
enum StructuredCloneTags {
|
enum StructuredCloneTags {
|
||||||
SCTAG_BASE = JS_SCTAG_USER_MIN,
|
SCTAG_BASE = JS_SCTAG_USER_MIN,
|
||||||
|
|
||||||
// These tags are used only for main thread structured clone.
|
// These tags are used only for main thread structured clone.
|
||||||
SCTAG_DOM_BLOB,
|
SCTAG_DOM_BLOB,
|
||||||
SCTAG_DOM_FILE,
|
|
||||||
|
// This tag is obsolete and exists only for backwards compatibility with
|
||||||
|
// existing IndexedDB databases.
|
||||||
|
SCTAG_DOM_FILE_WITHOUT_LASTMODIFIEDDATE,
|
||||||
|
|
||||||
SCTAG_DOM_FILELIST,
|
SCTAG_DOM_FILELIST,
|
||||||
SCTAG_DOM_FILEHANDLE,
|
SCTAG_DOM_FILEHANDLE,
|
||||||
|
SCTAG_DOM_FILE,
|
||||||
|
|
||||||
// These tags are used for both main thread and workers.
|
// These tags are used for both main thread and workers.
|
||||||
SCTAG_DOM_IMAGEDATA,
|
SCTAG_DOM_IMAGEDATA,
|
||||||
|
@ -175,9 +175,11 @@ DeviceStorageRequestParent::PostSuccessEvent::CancelableRun() {
|
|||||||
DeviceStorageRequestParent::PostBlobSuccessEvent::PostBlobSuccessEvent(DeviceStorageRequestParent* aParent,
|
DeviceStorageRequestParent::PostBlobSuccessEvent::PostBlobSuccessEvent(DeviceStorageRequestParent* aParent,
|
||||||
DeviceStorageFile* aFile,
|
DeviceStorageFile* aFile,
|
||||||
uint32_t aLength,
|
uint32_t aLength,
|
||||||
nsACString& aMimeType)
|
nsACString& aMimeType,
|
||||||
|
uint64_t aLastModifiedDate)
|
||||||
: CancelableRunnable(aParent)
|
: CancelableRunnable(aParent)
|
||||||
, mLength(aLength)
|
, mLength(aLength)
|
||||||
|
, mLastModificationDate(aLastModifiedDate)
|
||||||
, mFile(aFile)
|
, mFile(aFile)
|
||||||
, mMimeType(aMimeType)
|
, mMimeType(aMimeType)
|
||||||
{
|
{
|
||||||
@ -192,7 +194,7 @@ DeviceStorageRequestParent::PostBlobSuccessEvent::CancelableRun() {
|
|||||||
nsString mime;
|
nsString mime;
|
||||||
CopyASCIItoUTF16(mMimeType, mime);
|
CopyASCIItoUTF16(mMimeType, mime);
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMBlob> blob = new nsDOMFileFile(mFile->mPath, mime, mLength, mFile->mFile);
|
nsCOMPtr<nsIDOMBlob> blob = new nsDOMFileFile(mFile->mPath, mime, mLength, mFile->mFile, mLastModificationDate);
|
||||||
|
|
||||||
ContentParent* cp = static_cast<ContentParent*>(mParent->Manager());
|
ContentParent* cp = static_cast<ContentParent*>(mParent->Manager());
|
||||||
BlobParent* actor = cp->GetOrCreateActorForBlob(blob);
|
BlobParent* actor = cp->GetOrCreateActorForBlob(blob);
|
||||||
@ -374,7 +376,15 @@ DeviceStorageRequestParent::ReadFileEvent::CancelableRun()
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = new PostBlobSuccessEvent(mParent, mFile, fileSize, mMimeType);
|
PRTime modDate;
|
||||||
|
rv = mFile->mFile->GetLastModifiedTime(&modDate);
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
r = new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN);
|
||||||
|
NS_DispatchToMainThread(r);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = new PostBlobSuccessEvent(mParent, mFile, fileSize, mMimeType, modDate);
|
||||||
NS_DispatchToMainThread(r);
|
NS_DispatchToMainThread(r);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
@ -86,11 +86,12 @@ private:
|
|||||||
class PostBlobSuccessEvent : public CancelableRunnable
|
class PostBlobSuccessEvent : public CancelableRunnable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PostBlobSuccessEvent(DeviceStorageRequestParent* aParent, DeviceStorageFile* aFile, uint32_t aLength, nsACString& aMimeType);
|
PostBlobSuccessEvent(DeviceStorageRequestParent* aParent, DeviceStorageFile* aFile, uint32_t aLength, nsACString& aMimeType, uint64_t aLastModifiedDate);
|
||||||
virtual ~PostBlobSuccessEvent();
|
virtual ~PostBlobSuccessEvent();
|
||||||
virtual nsresult CancelableRun();
|
virtual nsresult CancelableRun();
|
||||||
private:
|
private:
|
||||||
uint32_t mLength;
|
uint32_t mLength;
|
||||||
|
uint64_t mLastModificationDate;
|
||||||
nsRefPtr<DeviceStorageFile> mFile;
|
nsRefPtr<DeviceStorageFile> mFile;
|
||||||
nsCString mMimeType;
|
nsCString mMimeType;
|
||||||
};
|
};
|
||||||
|
@ -61,6 +61,9 @@ function getSuccess(e) {
|
|||||||
ok(navigator.getDeviceStorage, "Should have getDeviceStorage");
|
ok(navigator.getDeviceStorage, "Should have getDeviceStorage");
|
||||||
|
|
||||||
ok(e.target.result.name == gFileName, "File name should match");
|
ok(e.target.result.name == gFileName, "File name should match");
|
||||||
|
ok(e.target.result.size > 0, "File size be greater than zero");
|
||||||
|
ok(e.target.result.type, "File should have a mime type");
|
||||||
|
ok(e.target.result.lastModifiedDate, "File should have a last modified date");
|
||||||
|
|
||||||
var name = e.target.result.name;
|
var name = e.target.result.name;
|
||||||
|
|
||||||
|
@ -604,12 +604,14 @@ ActorFromRemoteBlob(nsIDOMBlob* aBlob)
|
|||||||
|
|
||||||
inline
|
inline
|
||||||
bool
|
bool
|
||||||
ResolveMysteryBlob(nsIDOMBlob* aBlob, const nsString& aName,
|
ResolveMysteryFile(nsIDOMBlob* aBlob, const nsString& aName,
|
||||||
const nsString& aContentType, uint64_t aSize)
|
const nsString& aContentType, uint64_t aSize,
|
||||||
|
uint64_t aLastModifiedDate)
|
||||||
{
|
{
|
||||||
BlobChild* actor = ActorFromRemoteBlob(aBlob);
|
BlobChild* actor = ActorFromRemoteBlob(aBlob);
|
||||||
if (actor) {
|
if (actor) {
|
||||||
return actor->SetMysteryBlobInfo(aName, aContentType, aSize);
|
return actor->SetMysteryBlobInfo(aName, aContentType,
|
||||||
|
aSize, aLastModifiedDate);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1095,7 +1097,18 @@ IDBObjectStore::StructuredCloneReadCallback(JSContext* aCx,
|
|||||||
uint32_t aData,
|
uint32_t aData,
|
||||||
void* aClosure)
|
void* aClosure)
|
||||||
{
|
{
|
||||||
if (aTag == SCTAG_DOM_FILEHANDLE || aTag == SCTAG_DOM_BLOB ||
|
// We need to statically assert that our tag values are what we expect
|
||||||
|
// so that if people accidentally change them they notice.
|
||||||
|
MOZ_STATIC_ASSERT(SCTAG_DOM_BLOB == 0xFFFF8001 &&
|
||||||
|
SCTAG_DOM_FILE_WITHOUT_LASTMODIFIEDDATE == 0xFFFF8002 &&
|
||||||
|
SCTAG_DOM_FILEHANDLE == 0xFFFF8004 &&
|
||||||
|
SCTAG_DOM_FILE == 0xFFFF8005,
|
||||||
|
"You changed our structured clone tag values and just ate "
|
||||||
|
"everyone's IndexedDB data. I hope you are happy.");
|
||||||
|
|
||||||
|
if (aTag == SCTAG_DOM_FILE_WITHOUT_LASTMODIFIEDDATE ||
|
||||||
|
aTag == SCTAG_DOM_FILEHANDLE ||
|
||||||
|
aTag == SCTAG_DOM_BLOB ||
|
||||||
aTag == SCTAG_DOM_FILE) {
|
aTag == SCTAG_DOM_FILE) {
|
||||||
StructuredCloneReadInfo* cloneReadInfo =
|
StructuredCloneReadInfo* cloneReadInfo =
|
||||||
reinterpret_cast<StructuredCloneReadInfo*>(aClosure);
|
reinterpret_cast<StructuredCloneReadInfo*>(aClosure);
|
||||||
@ -1141,6 +1154,7 @@ IDBObjectStore::StructuredCloneReadCallback(JSContext* aCx,
|
|||||||
return JSVAL_TO_OBJECT(wrappedFileHandle);
|
return JSVAL_TO_OBJECT(wrappedFileHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If it's not a FileHandle, it's a Blob or a File.
|
||||||
uint64_t size;
|
uint64_t size;
|
||||||
if (!JS_ReadBytes(aReader, &size, sizeof(uint64_t))) {
|
if (!JS_ReadBytes(aReader, &size, sizeof(uint64_t))) {
|
||||||
NS_WARNING("Failed to read size!");
|
NS_WARNING("Failed to read size!");
|
||||||
@ -1196,7 +1210,15 @@ IDBObjectStore::StructuredCloneReadCallback(JSContext* aCx,
|
|||||||
return JSVAL_TO_OBJECT(wrappedBlob);
|
return JSVAL_TO_OBJECT(wrappedBlob);
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_ASSERTION(aTag == SCTAG_DOM_FILE, "Huh?!");
|
NS_ASSERTION(aTag == SCTAG_DOM_FILE ||
|
||||||
|
aTag == SCTAG_DOM_FILE_WITHOUT_LASTMODIFIEDDATE, "Huh?!");
|
||||||
|
|
||||||
|
uint64_t lastModifiedDate = UINT64_MAX;
|
||||||
|
if (aTag != SCTAG_DOM_FILE_WITHOUT_LASTMODIFIEDDATE &&
|
||||||
|
!JS_ReadBytes(aReader, &lastModifiedDate, sizeof(lastModifiedDate))) {
|
||||||
|
NS_WARNING("Failed to read lastModifiedDate");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
nsCString name;
|
nsCString name;
|
||||||
if (!StructuredCloneReadString(aReader, name)) {
|
if (!StructuredCloneReadString(aReader, name)) {
|
||||||
@ -1206,7 +1228,7 @@ IDBObjectStore::StructuredCloneReadCallback(JSContext* aCx,
|
|||||||
|
|
||||||
nsCOMPtr<nsIDOMFile> domFile;
|
nsCOMPtr<nsIDOMFile> domFile;
|
||||||
if (file.mFile) {
|
if (file.mFile) {
|
||||||
if (!ResolveMysteryBlob(file.mFile, convName, convType, size)) {
|
if (!ResolveMysteryFile(file.mFile, convName, convType, size, lastModifiedDate)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
domFile = do_QueryInterface(file.mFile);
|
domFile = do_QueryInterface(file.mFile);
|
||||||
@ -1320,6 +1342,14 @@ IDBObjectStore::StructuredCloneWriteCallback(JSContext* aCx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (file) {
|
if (file) {
|
||||||
|
uint64_t lastModifiedDate = 0;
|
||||||
|
if (NS_FAILED(file->GetMozLastModifiedDate(&lastModifiedDate))) {
|
||||||
|
NS_WARNING("Failed to get last modified date!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
lastModifiedDate = SwapBytes(lastModifiedDate);
|
||||||
|
|
||||||
nsString name;
|
nsString name;
|
||||||
if (NS_FAILED(file->GetName(name))) {
|
if (NS_FAILED(file->GetName(name))) {
|
||||||
NS_WARNING("Failed to get name!");
|
NS_WARNING("Failed to get name!");
|
||||||
@ -1328,7 +1358,8 @@ IDBObjectStore::StructuredCloneWriteCallback(JSContext* aCx,
|
|||||||
NS_ConvertUTF16toUTF8 convName(name);
|
NS_ConvertUTF16toUTF8 convName(name);
|
||||||
uint32_t convNameLength = SwapBytes(convName.Length());
|
uint32_t convNameLength = SwapBytes(convName.Length());
|
||||||
|
|
||||||
if (!JS_WriteBytes(aWriter, &convNameLength, sizeof(convNameLength)) ||
|
if (!JS_WriteBytes(aWriter, &lastModifiedDate, sizeof(lastModifiedDate)) ||
|
||||||
|
!JS_WriteBytes(aWriter, &convNameLength, sizeof(convNameLength)) ||
|
||||||
!JS_WriteBytes(aWriter, convName.get(), convName.Length())) {
|
!JS_WriteBytes(aWriter, convName.get(), convName.Length())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -584,6 +584,13 @@ private:
|
|||||||
public:
|
public:
|
||||||
NS_DECL_ISUPPORTS_INHERITED
|
NS_DECL_ISUPPORTS_INHERITED
|
||||||
|
|
||||||
|
RemoteBlob(const nsAString& aName, const nsAString& aContentType,
|
||||||
|
uint64_t aLength, uint64_t aModDate)
|
||||||
|
: nsDOMFile(aName, aContentType, aLength, aModDate), mActor(nullptr)
|
||||||
|
{
|
||||||
|
mImmutable = true;
|
||||||
|
}
|
||||||
|
|
||||||
RemoteBlob(const nsAString& aName, const nsAString& aContentType,
|
RemoteBlob(const nsAString& aName, const nsAString& aContentType,
|
||||||
uint64_t aLength)
|
uint64_t aLength)
|
||||||
: nsDOMFile(aName, aContentType, aLength), mActor(nullptr)
|
: nsDOMFile(aName, aContentType, aLength), mActor(nullptr)
|
||||||
@ -598,7 +605,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
RemoteBlob()
|
RemoteBlob()
|
||||||
: nsDOMFile(EmptyString(), EmptyString(), UINT64_MAX), mActor(nullptr)
|
: nsDOMFile(EmptyString(), EmptyString(), UINT64_MAX, UINT64_MAX)
|
||||||
|
, mActor(nullptr)
|
||||||
{
|
{
|
||||||
mImmutable = true;
|
mImmutable = true;
|
||||||
}
|
}
|
||||||
@ -651,6 +659,21 @@ public:
|
|||||||
{
|
{
|
||||||
return static_cast<typename ActorType::ProtocolType*>(mActor);
|
return static_cast<typename ActorType::ProtocolType*>(mActor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHOD
|
||||||
|
GetLastModifiedDate(JSContext* cx, JS::Value* aLastModifiedDate)
|
||||||
|
{
|
||||||
|
if (IsDateUnknown()) {
|
||||||
|
aLastModifiedDate->setNull();
|
||||||
|
} else {
|
||||||
|
JSObject* date = JS_NewDateObjectMsec(cx, mLastModificationDate);
|
||||||
|
if (!date) {
|
||||||
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
aLastModifiedDate->setObject(*date);
|
||||||
|
}
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <ActorFlavorEnum ActorFlavor>
|
template <ActorFlavorEnum ActorFlavor>
|
||||||
@ -686,7 +709,7 @@ Blob<ActorFlavor>::Blob(const BlobConstructorParams& aParams)
|
|||||||
aParams.get_FileBlobConstructorParams();
|
aParams.get_FileBlobConstructorParams();
|
||||||
remoteBlob =
|
remoteBlob =
|
||||||
new RemoteBlobType(params.name(), params.contentType(),
|
new RemoteBlobType(params.name(), params.contentType(),
|
||||||
params.length());
|
params.length(), params.modDate());
|
||||||
mBlobIsFile = true;
|
mBlobIsFile = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -770,16 +793,20 @@ template <ActorFlavorEnum ActorFlavor>
|
|||||||
bool
|
bool
|
||||||
Blob<ActorFlavor>::SetMysteryBlobInfo(const nsString& aName,
|
Blob<ActorFlavor>::SetMysteryBlobInfo(const nsString& aName,
|
||||||
const nsString& aContentType,
|
const nsString& aContentType,
|
||||||
uint64_t aLength)
|
uint64_t aLength,
|
||||||
|
uint64_t aLastModifiedDate)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
MOZ_ASSERT(mBlob);
|
MOZ_ASSERT(mBlob);
|
||||||
MOZ_ASSERT(mRemoteBlob);
|
MOZ_ASSERT(mRemoteBlob);
|
||||||
MOZ_ASSERT(aLength);
|
MOZ_ASSERT(aLength);
|
||||||
|
MOZ_ASSERT(aLastModifiedDate != UINT64_MAX);
|
||||||
|
|
||||||
ToConcreteBlob(mBlob)->SetLazyData(aName, aContentType, aLength);
|
ToConcreteBlob(mBlob)->SetLazyData(aName, aContentType,
|
||||||
|
aLength, aLastModifiedDate);
|
||||||
|
|
||||||
FileBlobConstructorParams params(aName, aContentType, aLength);
|
FileBlobConstructorParams params(aName, aContentType,
|
||||||
|
aLength, aLastModifiedDate);
|
||||||
return ProtocolType::SendResolveMystery(params);
|
return ProtocolType::SendResolveMystery(params);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -796,7 +823,8 @@ Blob<ActorFlavor>::SetMysteryBlobInfo(const nsString& aContentType,
|
|||||||
nsString voidString;
|
nsString voidString;
|
||||||
voidString.SetIsVoid(true);
|
voidString.SetIsVoid(true);
|
||||||
|
|
||||||
ToConcreteBlob(mBlob)->SetLazyData(voidString, aContentType, aLength);
|
ToConcreteBlob(mBlob)->SetLazyData(voidString, aContentType,
|
||||||
|
aLength, UINT64_MAX);
|
||||||
|
|
||||||
NormalBlobConstructorParams params(aContentType, aLength);
|
NormalBlobConstructorParams params(aContentType, aLength);
|
||||||
return ProtocolType::SendResolveMystery(params);
|
return ProtocolType::SendResolveMystery(params);
|
||||||
@ -890,14 +918,16 @@ Blob<ActorFlavor>::RecvResolveMystery(const ResolveMysteryParams& aParams)
|
|||||||
aParams.get_NormalBlobConstructorParams();
|
aParams.get_NormalBlobConstructorParams();
|
||||||
nsString voidString;
|
nsString voidString;
|
||||||
voidString.SetIsVoid(true);
|
voidString.SetIsVoid(true);
|
||||||
blob->SetLazyData(voidString, params.contentType(), params.length());
|
blob->SetLazyData(voidString, params.contentType(),
|
||||||
|
params.length(), UINT64_MAX);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case ResolveMysteryParams::TFileBlobConstructorParams: {
|
case ResolveMysteryParams::TFileBlobConstructorParams: {
|
||||||
const FileBlobConstructorParams& params =
|
const FileBlobConstructorParams& params =
|
||||||
aParams.get_FileBlobConstructorParams();
|
aParams.get_FileBlobConstructorParams();
|
||||||
blob->SetLazyData(params.name(), params.contentType(), params.length());
|
blob->SetLazyData(params.name(), params.contentType(),
|
||||||
|
params.length(), params.modDate());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,7 +173,7 @@ public:
|
|||||||
// Use this for files.
|
// Use this for files.
|
||||||
bool
|
bool
|
||||||
SetMysteryBlobInfo(const nsString& aName, const nsString& aContentType,
|
SetMysteryBlobInfo(const nsString& aName, const nsString& aContentType,
|
||||||
uint64_t aLength);
|
uint64_t aLength, uint64_t aLastModifiedDate);
|
||||||
|
|
||||||
// Use this for non-file blobs.
|
// Use this for non-file blobs.
|
||||||
bool
|
bool
|
||||||
|
@ -540,9 +540,11 @@ ContentChild::GetOrCreateActorForBlob(nsIDOMBlob* aBlob)
|
|||||||
|
|
||||||
BlobConstructorParams params;
|
BlobConstructorParams params;
|
||||||
|
|
||||||
if (blob->IsSizeUnknown()) {
|
if (blob->IsSizeUnknown() || blob->IsDateUnknown()) {
|
||||||
// We don't want to call GetSize yet since that may stat a file on the main
|
// We don't want to call GetSize or GetLastModifiedDate
|
||||||
// thread here. Instead we'll learn the size lazily from the other process.
|
// yet since that may stat a file on the main thread
|
||||||
|
// here. Instead we'll learn the size lazily from the
|
||||||
|
// other process.
|
||||||
params = MysteryBlobConstructorParams();
|
params = MysteryBlobConstructorParams();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -561,6 +563,9 @@ ContentChild::GetOrCreateActorForBlob(nsIDOMBlob* aBlob)
|
|||||||
rv = file->GetName(fileParams.name());
|
rv = file->GetName(fileParams.name());
|
||||||
NS_ENSURE_SUCCESS(rv, nullptr);
|
NS_ENSURE_SUCCESS(rv, nullptr);
|
||||||
|
|
||||||
|
rv = file->GetMozLastModifiedDate(&fileParams.modDate());
|
||||||
|
NS_ENSURE_SUCCESS(rv, nullptr);
|
||||||
|
|
||||||
fileParams.contentType() = contentType;
|
fileParams.contentType() = contentType;
|
||||||
fileParams.length() = length;
|
fileParams.length() = length;
|
||||||
|
|
||||||
|
@ -1238,9 +1238,11 @@ ContentParent::GetOrCreateActorForBlob(nsIDOMBlob* aBlob)
|
|||||||
|
|
||||||
BlobConstructorParams params;
|
BlobConstructorParams params;
|
||||||
|
|
||||||
if (blob->IsSizeUnknown()) {
|
if (blob->IsSizeUnknown() || /*blob->IsDateUnknown()*/ 0) {
|
||||||
// We don't want to call GetSize yet since that may stat a file on the main
|
// We don't want to call GetSize or GetLastModifiedDate
|
||||||
// thread here. Instead we'll learn the size lazily from the other process.
|
// yet since that may stat a file on the main thread
|
||||||
|
// here. Instead we'll learn the size lazily from the
|
||||||
|
// other process.
|
||||||
params = MysteryBlobConstructorParams();
|
params = MysteryBlobConstructorParams();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -1256,6 +1258,9 @@ ContentParent::GetOrCreateActorForBlob(nsIDOMBlob* aBlob)
|
|||||||
if (file) {
|
if (file) {
|
||||||
FileBlobConstructorParams fileParams;
|
FileBlobConstructorParams fileParams;
|
||||||
|
|
||||||
|
rv = file->GetMozLastModifiedDate(&fileParams.modDate());
|
||||||
|
NS_ENSURE_SUCCESS(rv, nullptr);
|
||||||
|
|
||||||
rv = file->GetName(fileParams.name());
|
rv = file->GetName(fileParams.name());
|
||||||
NS_ENSURE_SUCCESS(rv, nullptr);
|
NS_ENSURE_SUCCESS(rv, nullptr);
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@ struct FileBlobConstructorParams
|
|||||||
nsString name;
|
nsString name;
|
||||||
nsString contentType;
|
nsString contentType;
|
||||||
uint64_t length;
|
uint64_t length;
|
||||||
|
uint64_t modDate;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace dom
|
} // namespace dom
|
||||||
|
Loading…
Reference in New Issue
Block a user