mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1185381 - Make FileList clonable - patch 3 - FileListClonedData implementation, r=smaug
This commit is contained in:
parent
9e06b3f460
commit
1759db26d0
@ -21,6 +21,30 @@ NS_INTERFACE_MAP_END
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(FileList)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(FileList)
|
||||
|
||||
/* static */ already_AddRefed<FileList>
|
||||
FileList::Create(nsISupports* aParent, FileListClonedData* aData)
|
||||
{
|
||||
MOZ_ASSERT(aData);
|
||||
|
||||
nsRefPtr<FileList> fileList = new FileList(aParent);
|
||||
|
||||
const nsTArray<nsRefPtr<BlobImpl>>& blobImpls = aData->BlobImpls();
|
||||
for (uint32_t i = 0; i < blobImpls.Length(); ++i) {
|
||||
const nsRefPtr<BlobImpl>& blobImpl = blobImpls[i];
|
||||
MOZ_ASSERT(blobImpl);
|
||||
MOZ_ASSERT(blobImpl->IsFile());
|
||||
|
||||
nsRefPtr<File> file = File::Create(aParent, blobImpl);
|
||||
MOZ_ASSERT(file);
|
||||
|
||||
if (NS_WARN_IF(!fileList->Append(file))) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return fileList.forget();
|
||||
}
|
||||
|
||||
JSObject*
|
||||
FileList::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
||||
{
|
||||
@ -43,5 +67,19 @@ FileList::Item(uint32_t aIndex, nsISupports** aFile)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
already_AddRefed<FileListClonedData>
|
||||
FileList::CreateClonedData() const
|
||||
{
|
||||
nsTArray<nsRefPtr<BlobImpl>> blobImpls;
|
||||
for (uint32_t i = 0; i < mFiles.Length(); ++i) {
|
||||
blobImpls.AppendElement(mFiles[i]->Impl());
|
||||
}
|
||||
|
||||
nsRefPtr<FileListClonedData> data = new FileListClonedData(blobImpls);
|
||||
return data.forget();
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS0(FileListClonedData)
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
@ -13,8 +13,30 @@
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class BlobImpls;
|
||||
class File;
|
||||
|
||||
class FileListClonedData final : public nsISupports
|
||||
{
|
||||
public:
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
|
||||
explicit FileListClonedData(const nsTArray<nsRefPtr<BlobImpl>>& aBlobImpls)
|
||||
: mBlobImpls(aBlobImpls)
|
||||
{}
|
||||
|
||||
const nsTArray<nsRefPtr<BlobImpl>>& BlobImpls() const
|
||||
{
|
||||
return mBlobImpls;
|
||||
}
|
||||
|
||||
private:
|
||||
~FileListClonedData()
|
||||
{}
|
||||
|
||||
const nsTArray<nsRefPtr<BlobImpl>> mBlobImpls;
|
||||
};
|
||||
|
||||
class FileList final : public nsIDOMFileList,
|
||||
public nsWrapperCache
|
||||
{
|
||||
@ -28,6 +50,9 @@ public:
|
||||
: mParent(aParent)
|
||||
{}
|
||||
|
||||
static already_AddRefed<FileList>
|
||||
Create(nsISupports* aParent, FileListClonedData* aData);
|
||||
|
||||
virtual JSObject* WrapObject(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
@ -89,6 +114,9 @@ public:
|
||||
return mFiles.Length();
|
||||
}
|
||||
|
||||
// Useful for cloning
|
||||
already_AddRefed<FileListClonedData> CreateClonedData() const;
|
||||
|
||||
private:
|
||||
~FileList() {}
|
||||
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "MessageEvent.h"
|
||||
#include "mozilla/dom/BlobBinding.h"
|
||||
#include "mozilla/dom/FileList.h"
|
||||
#include "mozilla/dom/FileListBinding.h"
|
||||
#include "mozilla/dom/MessagePort.h"
|
||||
#include "mozilla/dom/MessagePortBinding.h"
|
||||
#include "mozilla/dom/PMessagePort.h"
|
||||
@ -86,12 +87,27 @@ PostMessageEvent::ReadStructuredClone(JSContext* cx,
|
||||
if (tag == SCTAG_DOM_FILELIST) {
|
||||
NS_ASSERTION(!data, "Data should be empty");
|
||||
|
||||
nsISupports* supports;
|
||||
if (JS_ReadBytes(reader, &supports, sizeof(supports))) {
|
||||
// What we get back from the reader is a FileListClonedData.
|
||||
// From that we create a new FileList.
|
||||
FileListClonedData* fileListClonedData;
|
||||
if (JS_ReadBytes(reader, &fileListClonedData, sizeof(fileListClonedData))) {
|
||||
MOZ_ASSERT(fileListClonedData);
|
||||
|
||||
// nsRefPtr<FileList> 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, supports, &val))) {
|
||||
return val.toObjectOrNull();
|
||||
{
|
||||
nsRefPtr<FileList> fileList =
|
||||
FileList::Create(scInfo->window, fileListClonedData);
|
||||
if (!fileList || !ToJSValue(cx, fileList, &val)) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return &val.toObject();
|
||||
}
|
||||
}
|
||||
|
||||
@ -127,21 +143,20 @@ PostMessageEvent::WriteStructuredClone(JSContext* cx,
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIXPConnectWrappedNative> wrappedNative;
|
||||
nsContentUtils::XPConnect()->
|
||||
GetWrappedNativeOfJSObject(cx, obj, getter_AddRefs(wrappedNative));
|
||||
if (wrappedNative) {
|
||||
uint32_t scTag = 0;
|
||||
nsISupports* supports = wrappedNative->Native();
|
||||
|
||||
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)) &&
|
||||
scInfo->event->StoreISupports(supports);
|
||||
// See if this is a FileList object.
|
||||
{
|
||||
FileList* fileList = nullptr;
|
||||
if (NS_SUCCEEDED(UNWRAP_OBJECT(FileList, obj, fileList))) {
|
||||
nsRefPtr<FileListClonedData> fileListClonedData =
|
||||
fileList->CreateClonedData();
|
||||
MOZ_ASSERT(fileListClonedData);
|
||||
FileListClonedData* ptr = fileListClonedData.get();
|
||||
if (JS_WriteUint32Pair(writer, SCTAG_DOM_FILELIST, 0) &&
|
||||
JS_WriteBytes(writer, &ptr, sizeof(ptr))) {
|
||||
scInfo->event->StoreISupports(fileListClonedData);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const JSStructuredCloneCallbacks* runtimeCallbacks =
|
||||
|
Loading…
Reference in New Issue
Block a user