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_
|
||||
...
|
||||
}
|
||||
{
|
||||
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
|
||||
SetLazyData(const nsAString& aName, const nsAString& aContentType,
|
||||
uint64_t aLength)
|
||||
uint64_t aLength, uint64_t aLastModifiedDate)
|
||||
{
|
||||
NS_ASSERTION(aLength, "must have length");
|
||||
|
||||
mName = aName;
|
||||
mContentType = aContentType;
|
||||
mLength = aLength;
|
||||
|
||||
mLastModificationDate = aLastModifiedDate;
|
||||
mIsFile = !aName.IsVoid();
|
||||
}
|
||||
|
||||
@ -70,11 +70,25 @@ public:
|
||||
return mLength == UINT64_MAX;
|
||||
}
|
||||
|
||||
bool IsDateUnknown() const
|
||||
{
|
||||
return mIsFile && mLastModificationDate == UINT64_MAX;
|
||||
}
|
||||
|
||||
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,
|
||||
uint64_t aLength)
|
||||
: 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
|
||||
mContentType.SetIsVoid(false);
|
||||
@ -82,7 +96,7 @@ protected:
|
||||
|
||||
nsDOMFileBase(const nsAString& aContentType, uint64_t aLength)
|
||||
: mIsFile(false), mImmutable(false), mContentType(aContentType),
|
||||
mStart(0), mLength(aLength)
|
||||
mStart(0), mLength(aLength), mLastModificationDate(UINT64_MAX)
|
||||
{
|
||||
// Ensure non-null mContentType by default
|
||||
mContentType.SetIsVoid(false);
|
||||
@ -91,7 +105,7 @@ protected:
|
||||
nsDOMFileBase(const nsAString& aContentType, uint64_t aStart,
|
||||
uint64_t aLength)
|
||||
: mIsFile(false), mImmutable(false), mContentType(aContentType),
|
||||
mStart(aStart), mLength(aLength)
|
||||
mStart(aStart), mLength(aLength), mLastModificationDate(UINT64_MAX)
|
||||
{
|
||||
NS_ASSERTION(aLength != UINT64_MAX,
|
||||
"Must know length when creating slice");
|
||||
@ -127,12 +141,15 @@ protected:
|
||||
|
||||
bool mIsFile;
|
||||
bool mImmutable;
|
||||
|
||||
nsString mContentType;
|
||||
nsString mName;
|
||||
|
||||
uint64_t mStart;
|
||||
uint64_t mLength;
|
||||
|
||||
uint64_t mLastModificationDate;
|
||||
|
||||
// Protected by IndexedDatabaseManager::FileMutex()
|
||||
nsTArray<nsRefPtr<FileInfo> > mFileInfos;
|
||||
};
|
||||
@ -140,6 +157,11 @@ protected:
|
||||
class nsDOMFile : public nsDOMFileBase
|
||||
{
|
||||
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,
|
||||
uint64_t aLength)
|
||||
: nsDOMFileBase(aName, aContentType, aLength)
|
||||
@ -183,7 +205,7 @@ class nsDOMFileFile : public nsDOMFile,
|
||||
public:
|
||||
// Create as a file
|
||||
nsDOMFileFile(nsIFile *aFile)
|
||||
: nsDOMFile(EmptyString(), EmptyString(), UINT64_MAX),
|
||||
: nsDOMFile(EmptyString(), EmptyString(), UINT64_MAX, UINT64_MAX),
|
||||
mFile(aFile), mWholeFile(true), mStoredFile(false)
|
||||
{
|
||||
NS_ASSERTION(mFile, "must have file");
|
||||
@ -195,7 +217,15 @@ public:
|
||||
// Create as a file
|
||||
nsDOMFileFile(const nsAString& aName, const nsAString& aContentType,
|
||||
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)
|
||||
{
|
||||
NS_ASSERTION(mFile, "must have file");
|
||||
@ -213,7 +243,7 @@ public:
|
||||
|
||||
// Create as a file with custom name
|
||||
nsDOMFileFile(nsIFile *aFile, const nsAString& aName)
|
||||
: nsDOMFile(aName, EmptyString(), UINT64_MAX),
|
||||
: nsDOMFile(aName, EmptyString(), UINT64_MAX, UINT64_MAX),
|
||||
mFile(aFile), mWholeFile(true), mStoredFile(false)
|
||||
{
|
||||
NS_ASSERTION(mFile, "must have file");
|
||||
@ -225,7 +255,7 @@ public:
|
||||
nsDOMFileFile(const nsAString& aName, const nsAString& aContentType,
|
||||
uint64_t aLength, nsIFile* aFile,
|
||||
FileInfo* aFileInfo)
|
||||
: nsDOMFile(aName, aContentType, aLength),
|
||||
: nsDOMFile(aName, aContentType, aLength, UINT64_MAX),
|
||||
mFile(aFile), mWholeFile(true), mStoredFile(true)
|
||||
{
|
||||
NS_ASSERTION(mFile, "must have file");
|
||||
@ -244,7 +274,7 @@ public:
|
||||
|
||||
// Create as a file to be later initialized
|
||||
nsDOMFileFile()
|
||||
: nsDOMFile(EmptyString(), EmptyString(), UINT64_MAX),
|
||||
: nsDOMFile(EmptyString(), EmptyString(), UINT64_MAX, UINT64_MAX),
|
||||
mWholeFile(true), mStoredFile(false)
|
||||
{
|
||||
// Lazily get the content type and size
|
||||
@ -264,7 +294,8 @@ public:
|
||||
// Overrides
|
||||
NS_IMETHOD GetSize(uint64_t* aSize);
|
||||
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 GetInternalStream(nsIInputStream**);
|
||||
|
||||
@ -328,7 +359,7 @@ public:
|
||||
uint64_t aLength,
|
||||
const nsAString& aName,
|
||||
const nsAString& aContentType)
|
||||
: nsDOMFile(aName, aContentType, aLength),
|
||||
: nsDOMFile(aName, aContentType, aLength, UINT64_MAX),
|
||||
mDataOwner(new DataOwner(aMemoryBuffer))
|
||||
{
|
||||
NS_ASSERTION(mDataOwner && mDataOwner->mData, "must have data");
|
||||
|
@ -28,7 +28,7 @@ interface nsIURI;
|
||||
interface nsIPrincipal;
|
||||
interface nsIDOMBlob;
|
||||
|
||||
[scriptable, builtinclass, uuid(16e3f8d1-7f31-48cc-93f5-9c931a977cf6)]
|
||||
[scriptable, builtinclass, uuid(52d22585-7737-460e-9731-c658df03304a)]
|
||||
interface nsIDOMBlob : nsISupports
|
||||
{
|
||||
readonly attribute unsigned long long size;
|
||||
@ -73,4 +73,6 @@ interface nsIDOMFile : nsIDOMBlob
|
||||
|
||||
// This performs no security checks!
|
||||
[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
|
||||
// anonymous content subtree or event is dispatched somewhere inside XBL.
|
||||
if (isAnonForEvents) {
|
||||
#ifdef DEBUG
|
||||
// If a DOM event is explicitly dispatched using node.dispatchEvent(), then
|
||||
// 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,
|
||||
"Mutation event dispatched in native anonymous content!?!");
|
||||
#endif
|
||||
aVisitor.mEventTargetAtParent = parent;
|
||||
} else if (parent && aVisitor.mOriginalTargetIsInAnon) {
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(aVisitor.mEvent->target));
|
||||
|
@ -174,6 +174,14 @@ nsDOMFileBase::GetType(nsAString &aType)
|
||||
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
|
||||
// than 0
|
||||
static void
|
||||
@ -498,10 +506,20 @@ nsDOMFileFile::GetMozFullPathInternal(nsAString &aFilename)
|
||||
}
|
||||
|
||||
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;
|
||||
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);
|
||||
if (date) {
|
||||
aLastModifiedDate->setObject(*date);
|
||||
@ -562,6 +580,14 @@ nsDOMFileFile::GetType(nsAString &aType)
|
||||
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 =
|
||||
nsIFileInputStream::CLOSE_ON_EOF |
|
||||
nsIFileInputStream::REOPEN_ON_REWIND |
|
||||
|
@ -10,14 +10,21 @@
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
// CHANGING THE ORDER/PLACEMENT OF EXISTING ENUM VALUES MAY BREAK INDEXEDDB.
|
||||
// PROCEED WITH EXTREME CAUTION.
|
||||
enum StructuredCloneTags {
|
||||
SCTAG_BASE = JS_SCTAG_USER_MIN,
|
||||
|
||||
// These tags are used only for main thread structured clone.
|
||||
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_FILEHANDLE,
|
||||
SCTAG_DOM_FILE,
|
||||
|
||||
// These tags are used for both main thread and workers.
|
||||
SCTAG_DOM_IMAGEDATA,
|
||||
|
@ -175,9 +175,11 @@ DeviceStorageRequestParent::PostSuccessEvent::CancelableRun() {
|
||||
DeviceStorageRequestParent::PostBlobSuccessEvent::PostBlobSuccessEvent(DeviceStorageRequestParent* aParent,
|
||||
DeviceStorageFile* aFile,
|
||||
uint32_t aLength,
|
||||
nsACString& aMimeType)
|
||||
nsACString& aMimeType,
|
||||
uint64_t aLastModifiedDate)
|
||||
: CancelableRunnable(aParent)
|
||||
, mLength(aLength)
|
||||
, mLastModificationDate(aLastModifiedDate)
|
||||
, mFile(aFile)
|
||||
, mMimeType(aMimeType)
|
||||
{
|
||||
@ -192,7 +194,7 @@ DeviceStorageRequestParent::PostBlobSuccessEvent::CancelableRun() {
|
||||
nsString 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());
|
||||
BlobParent* actor = cp->GetOrCreateActorForBlob(blob);
|
||||
@ -374,7 +376,15 @@ DeviceStorageRequestParent::ReadFileEvent::CancelableRun()
|
||||
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);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -86,11 +86,12 @@ private:
|
||||
class PostBlobSuccessEvent : public CancelableRunnable
|
||||
{
|
||||
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 nsresult CancelableRun();
|
||||
private:
|
||||
uint32_t mLength;
|
||||
uint64_t mLastModificationDate;
|
||||
nsRefPtr<DeviceStorageFile> mFile;
|
||||
nsCString mMimeType;
|
||||
};
|
||||
|
@ -61,6 +61,9 @@ function getSuccess(e) {
|
||||
ok(navigator.getDeviceStorage, "Should have getDeviceStorage");
|
||||
|
||||
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;
|
||||
|
||||
|
@ -604,12 +604,14 @@ ActorFromRemoteBlob(nsIDOMBlob* aBlob)
|
||||
|
||||
inline
|
||||
bool
|
||||
ResolveMysteryBlob(nsIDOMBlob* aBlob, const nsString& aName,
|
||||
const nsString& aContentType, uint64_t aSize)
|
||||
ResolveMysteryFile(nsIDOMBlob* 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);
|
||||
return actor->SetMysteryBlobInfo(aName, aContentType,
|
||||
aSize, aLastModifiedDate);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -1095,7 +1097,18 @@ IDBObjectStore::StructuredCloneReadCallback(JSContext* aCx,
|
||||
uint32_t aData,
|
||||
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) {
|
||||
StructuredCloneReadInfo* cloneReadInfo =
|
||||
reinterpret_cast<StructuredCloneReadInfo*>(aClosure);
|
||||
@ -1141,6 +1154,7 @@ IDBObjectStore::StructuredCloneReadCallback(JSContext* aCx,
|
||||
return JSVAL_TO_OBJECT(wrappedFileHandle);
|
||||
}
|
||||
|
||||
// If it's not a FileHandle, it's a Blob or a File.
|
||||
uint64_t size;
|
||||
if (!JS_ReadBytes(aReader, &size, sizeof(uint64_t))) {
|
||||
NS_WARNING("Failed to read size!");
|
||||
@ -1196,7 +1210,15 @@ IDBObjectStore::StructuredCloneReadCallback(JSContext* aCx,
|
||||
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;
|
||||
if (!StructuredCloneReadString(aReader, name)) {
|
||||
@ -1206,7 +1228,7 @@ IDBObjectStore::StructuredCloneReadCallback(JSContext* aCx,
|
||||
|
||||
nsCOMPtr<nsIDOMFile> domFile;
|
||||
if (file.mFile) {
|
||||
if (!ResolveMysteryBlob(file.mFile, convName, convType, size)) {
|
||||
if (!ResolveMysteryFile(file.mFile, convName, convType, size, lastModifiedDate)) {
|
||||
return nullptr;
|
||||
}
|
||||
domFile = do_QueryInterface(file.mFile);
|
||||
@ -1320,6 +1342,14 @@ IDBObjectStore::StructuredCloneWriteCallback(JSContext* aCx,
|
||||
}
|
||||
|
||||
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;
|
||||
if (NS_FAILED(file->GetName(name))) {
|
||||
NS_WARNING("Failed to get name!");
|
||||
@ -1328,7 +1358,8 @@ IDBObjectStore::StructuredCloneWriteCallback(JSContext* aCx,
|
||||
NS_ConvertUTF16toUTF8 convName(name);
|
||||
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())) {
|
||||
return false;
|
||||
}
|
||||
|
@ -584,6 +584,13 @@ private:
|
||||
public:
|
||||
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,
|
||||
uint64_t aLength)
|
||||
: nsDOMFile(aName, aContentType, aLength), mActor(nullptr)
|
||||
@ -598,7 +605,8 @@ public:
|
||||
}
|
||||
|
||||
RemoteBlob()
|
||||
: nsDOMFile(EmptyString(), EmptyString(), UINT64_MAX), mActor(nullptr)
|
||||
: nsDOMFile(EmptyString(), EmptyString(), UINT64_MAX, UINT64_MAX)
|
||||
, mActor(nullptr)
|
||||
{
|
||||
mImmutable = true;
|
||||
}
|
||||
@ -651,6 +659,21 @@ public:
|
||||
{
|
||||
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>
|
||||
@ -686,7 +709,7 @@ Blob<ActorFlavor>::Blob(const BlobConstructorParams& aParams)
|
||||
aParams.get_FileBlobConstructorParams();
|
||||
remoteBlob =
|
||||
new RemoteBlobType(params.name(), params.contentType(),
|
||||
params.length());
|
||||
params.length(), params.modDate());
|
||||
mBlobIsFile = true;
|
||||
break;
|
||||
}
|
||||
@ -770,16 +793,20 @@ template <ActorFlavorEnum ActorFlavor>
|
||||
bool
|
||||
Blob<ActorFlavor>::SetMysteryBlobInfo(const nsString& aName,
|
||||
const nsString& aContentType,
|
||||
uint64_t aLength)
|
||||
uint64_t aLength,
|
||||
uint64_t aLastModifiedDate)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mBlob);
|
||||
MOZ_ASSERT(mRemoteBlob);
|
||||
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);
|
||||
}
|
||||
|
||||
@ -796,7 +823,8 @@ Blob<ActorFlavor>::SetMysteryBlobInfo(const nsString& aContentType,
|
||||
nsString voidString;
|
||||
voidString.SetIsVoid(true);
|
||||
|
||||
ToConcreteBlob(mBlob)->SetLazyData(voidString, aContentType, aLength);
|
||||
ToConcreteBlob(mBlob)->SetLazyData(voidString, aContentType,
|
||||
aLength, UINT64_MAX);
|
||||
|
||||
NormalBlobConstructorParams params(aContentType, aLength);
|
||||
return ProtocolType::SendResolveMystery(params);
|
||||
@ -890,14 +918,16 @@ Blob<ActorFlavor>::RecvResolveMystery(const ResolveMysteryParams& aParams)
|
||||
aParams.get_NormalBlobConstructorParams();
|
||||
nsString voidString;
|
||||
voidString.SetIsVoid(true);
|
||||
blob->SetLazyData(voidString, params.contentType(), params.length());
|
||||
blob->SetLazyData(voidString, params.contentType(),
|
||||
params.length(), UINT64_MAX);
|
||||
break;
|
||||
}
|
||||
|
||||
case ResolveMysteryParams::TFileBlobConstructorParams: {
|
||||
const FileBlobConstructorParams& params =
|
||||
aParams.get_FileBlobConstructorParams();
|
||||
blob->SetLazyData(params.name(), params.contentType(), params.length());
|
||||
blob->SetLazyData(params.name(), params.contentType(),
|
||||
params.length(), params.modDate());
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -173,7 +173,7 @@ public:
|
||||
// Use this for files.
|
||||
bool
|
||||
SetMysteryBlobInfo(const nsString& aName, const nsString& aContentType,
|
||||
uint64_t aLength);
|
||||
uint64_t aLength, uint64_t aLastModifiedDate);
|
||||
|
||||
// Use this for non-file blobs.
|
||||
bool
|
||||
|
@ -540,9 +540,11 @@ ContentChild::GetOrCreateActorForBlob(nsIDOMBlob* aBlob)
|
||||
|
||||
BlobConstructorParams params;
|
||||
|
||||
if (blob->IsSizeUnknown()) {
|
||||
// We don't want to call GetSize yet since that may stat a file on the main
|
||||
// thread here. Instead we'll learn the size lazily from the other process.
|
||||
if (blob->IsSizeUnknown() || blob->IsDateUnknown()) {
|
||||
// We don't want to call GetSize or GetLastModifiedDate
|
||||
// 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();
|
||||
}
|
||||
else {
|
||||
@ -561,6 +563,9 @@ ContentChild::GetOrCreateActorForBlob(nsIDOMBlob* aBlob)
|
||||
rv = file->GetName(fileParams.name());
|
||||
NS_ENSURE_SUCCESS(rv, nullptr);
|
||||
|
||||
rv = file->GetMozLastModifiedDate(&fileParams.modDate());
|
||||
NS_ENSURE_SUCCESS(rv, nullptr);
|
||||
|
||||
fileParams.contentType() = contentType;
|
||||
fileParams.length() = length;
|
||||
|
||||
|
@ -1238,9 +1238,11 @@ ContentParent::GetOrCreateActorForBlob(nsIDOMBlob* aBlob)
|
||||
|
||||
BlobConstructorParams params;
|
||||
|
||||
if (blob->IsSizeUnknown()) {
|
||||
// We don't want to call GetSize yet since that may stat a file on the main
|
||||
// thread here. Instead we'll learn the size lazily from the other process.
|
||||
if (blob->IsSizeUnknown() || /*blob->IsDateUnknown()*/ 0) {
|
||||
// We don't want to call GetSize or GetLastModifiedDate
|
||||
// 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();
|
||||
}
|
||||
else {
|
||||
@ -1256,6 +1258,9 @@ ContentParent::GetOrCreateActorForBlob(nsIDOMBlob* aBlob)
|
||||
if (file) {
|
||||
FileBlobConstructorParams fileParams;
|
||||
|
||||
rv = file->GetMozLastModifiedDate(&fileParams.modDate());
|
||||
NS_ENSURE_SUCCESS(rv, nullptr);
|
||||
|
||||
rv = file->GetName(fileParams.name());
|
||||
NS_ENSURE_SUCCESS(rv, nullptr);
|
||||
|
||||
|
@ -28,6 +28,7 @@ struct FileBlobConstructorParams
|
||||
nsString name;
|
||||
nsString contentType;
|
||||
uint64_t length;
|
||||
uint64_t modDate;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
Loading…
Reference in New Issue
Block a user