Bug 1751681 - Add Serializable to OPFS interfaces. r=dom-storage-reviewers,jari,asuth

Differential Revision: https://phabricator.services.mozilla.com/D137648
This commit is contained in:
Randell Jesup 2022-09-06 21:37:30 +00:00
Родитель 5a2d29ad92
Коммит 4cfe3f5d9a
11 изменённых файлов: 238 добавлений и 9 удалений

Просмотреть файл

@ -210,7 +210,10 @@ void AssertTagValues() {
SCTAG_DOM_DOMMATRIX == 0xffff8013 &&
SCTAG_DOM_URLSEARCHPARAMS == 0xffff8014 &&
SCTAG_DOM_DOMMATRIXREADONLY == 0xffff8015 &&
SCTAG_DOM_STRUCTUREDCLONETESTER == 0xffff8018,
SCTAG_DOM_STRUCTUREDCLONETESTER == 0xffff8018 &&
SCTAG_DOM_FILESYSTEMHANDLE == 0xffff8019 &&
SCTAG_DOM_FILESYSTEMFILEHANDLE == 0xffff801a &&
SCTAG_DOM_FILESYSTEMDIRECTORYHANDLE == 0xffff801b,
"Something has changed the sctag values. This is wrong!");
}

Просмотреть файл

@ -105,8 +105,20 @@ enum StructuredCloneTags : uint32_t {
// IDB.
SCTAG_DOM_STRUCTUREDCLONETESTER,
// IMPORTANT: Don't change the order of these enum values. You could break
// IDB.
SCTAG_DOM_FILESYSTEMHANDLE,
// IMPORTANT: Don't change the order of these enum values. You could break
// IDB.
SCTAG_DOM_FILESYSTEMFILEHANDLE,
// IMPORTANT: Don't change the order of these enum values. You could break
// IDB.
SCTAG_DOM_FILESYSTEMDIRECTORYHANDLE,
// If you are planning to add new tags which could be used by IndexedDB,
// consider to use empty slots. See EMPTY_SLOT_x
// consider to use an empty slot. See EMPTY_SLOT_x
// Please update the static assertions in StructuredCloneHolder.cpp and in
// IDBObjectStore.cpp, method CommonStructuredCloneReadCallback.

Просмотреть файл

@ -8,6 +8,8 @@
#include "FileSystemDirectoryIteratorFactory.h"
#include "fs/FileSystemRequestHandler.h"
#include "js/StructuredClone.h"
#include "js/TypeDecls.h"
#include "mozilla/ErrorResult.h"
#include "mozilla/dom/FileSystemDirectoryHandleBinding.h"
#include "mozilla/dom/FileSystemDirectoryIterator.h"
@ -16,6 +18,7 @@
#include "mozilla/dom/PFileSystemManager.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/StorageManager.h"
#include "nsJSUtils.h"
namespace mozilla::dom {
@ -137,4 +140,31 @@ already_AddRefed<Promise> FileSystemDirectoryHandle::Resolve(
return promise.forget();
}
// [Serializable] implementation
// static
already_AddRefed<FileSystemDirectoryHandle>
FileSystemDirectoryHandle::ReadStructuredClone(
JSContext* aCx, nsIGlobalObject* aGlobal,
JSStructuredCloneReader* aReader) {
uint32_t kind = static_cast<uint32_t>(FileSystemHandleKind::EndGuard_);
if (!JS_ReadBytes(aReader, reinterpret_cast<void*>(&kind),
sizeof(uint32_t))) {
return nullptr;
}
if (kind != static_cast<uint32_t>(FileSystemHandleKind::Directory)) {
return nullptr;
}
RefPtr<FileSystemDirectoryHandle> result =
FileSystemHandle::ConstructDirectoryHandle(aCx, aGlobal, aReader);
if (!result) {
return nullptr;
}
return result.forget();
}
} // namespace mozilla::dom

Просмотреть файл

@ -69,6 +69,11 @@ class FileSystemDirectoryHandle final : public FileSystemHandle {
already_AddRefed<Promise> Resolve(FileSystemHandle& aPossibleDescendant,
ErrorResult& aError);
// [Serializable]
static already_AddRefed<FileSystemDirectoryHandle> ReadStructuredClone(
JSContext* aCx, nsIGlobalObject* aGlobal,
JSStructuredCloneReader* aReader);
private:
~FileSystemDirectoryHandle() = default;
};

Просмотреть файл

@ -7,6 +7,8 @@
#include "FileSystemFileHandle.h"
#include "fs/FileSystemRequestHandler.h"
#include "js/StructuredClone.h"
#include "js/TypeDecls.h"
#include "mozilla/ErrorResult.h"
#include "mozilla/dom/FileSystemFileHandleBinding.h"
#include "mozilla/dom/FileSystemHandleBinding.h"
@ -80,4 +82,31 @@ already_AddRefed<Promise> FileSystemFileHandle::CreateSyncAccessHandle(
return promise.forget();
}
// [Serializable] implementation
// static
already_AddRefed<FileSystemFileHandle>
FileSystemFileHandle::ReadStructuredClone(JSContext* aCx,
nsIGlobalObject* aGlobal,
JSStructuredCloneReader* aReader) {
uint32_t kind = static_cast<uint32_t>(FileSystemHandleKind::EndGuard_);
if (!JS_ReadBytes(aReader, reinterpret_cast<void*>(&kind),
sizeof(uint32_t))) {
return nullptr;
}
if (kind != static_cast<uint32_t>(FileSystemHandleKind::File)) {
return nullptr;
}
RefPtr<FileSystemFileHandle> result =
FileSystemHandle::ConstructFileHandle(aCx, aGlobal, aReader);
if (!result) {
return nullptr;
}
return result.forget();
}
} // namespace mozilla::dom

Просмотреть файл

@ -46,6 +46,11 @@ class FileSystemFileHandle final : public FileSystemHandle {
already_AddRefed<Promise> CreateSyncAccessHandle(ErrorResult& aError);
// [Serializable]
static already_AddRefed<FileSystemFileHandle> ReadStructuredClone(
JSContext* aCx, nsIGlobalObject* aGlobal,
JSStructuredCloneReader* aReader);
private:
~FileSystemFileHandle() = default;
};

Просмотреть файл

@ -5,15 +5,52 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "FileSystemHandle.h"
#include "fs/FileSystemRequestHandler.h"
#include "FileSystemDirectoryHandle.h"
#include "FileSystemFileHandle.h"
#include "fs/FileSystemRequestHandler.h"
#include "js/StructuredClone.h"
#include "mozilla/ErrorResult.h"
#include "mozilla/dom/FileSystemHandleBinding.h"
#include "mozilla/dom/FileSystemManager.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/StorageManager.h"
#include "xpcpublic.h"
namespace mozilla::dom {
namespace {
bool ConstructHandleMetadata(JSContext* aCx, JSStructuredCloneReader* aReader,
const bool aDirectory,
fs::FileSystemEntryMetadata& aMetadata) {
using namespace mozilla::dom::fs;
EntryId entryId;
if (!entryId.SetLength(32u, fallible)) {
return false;
}
if (!JS_ReadBytes(aReader, static_cast<void*>(entryId.BeginWriting()), 32u)) {
return false;
}
JS::Rooted<JSString*> tmpVal(aCx);
if (!JS_ReadString(aReader, &tmpVal)) {
return false;
}
Name name;
if (!AssignJSString(aCx, name, tmpVal)) {
return false;
}
aMetadata = fs::FileSystemEntryMetadata(entryId, name, aDirectory);
return true;
}
} // namespace
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(FileSystemHandle)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsISupports)
@ -45,6 +82,50 @@ FileSystemHandle::FileSystemHandle(
MOZ_ASSERT(!mMetadata.entryId().IsEmpty());
}
// [Serializable] implementation
// static
already_AddRefed<FileSystemFileHandle> FileSystemHandle::ConstructFileHandle(
JSContext* aCx, nsIGlobalObject* aGlobal,
JSStructuredCloneReader* aReader) {
using namespace mozilla::dom::fs;
FileSystemEntryMetadata metadata;
if (!ConstructHandleMetadata(aCx, aReader, /* aDirectory */ false,
metadata)) {
return nullptr;
}
// XXX Get the manager from Navigator!
auto fileSystemManager = MakeRefPtr<FileSystemManager>(aGlobal, nullptr);
RefPtr<FileSystemFileHandle> fsHandle =
new FileSystemFileHandle(aGlobal, fileSystemManager, metadata);
return fsHandle.forget();
}
// static
already_AddRefed<FileSystemDirectoryHandle>
FileSystemHandle::ConstructDirectoryHandle(JSContext* aCx,
nsIGlobalObject* aGlobal,
JSStructuredCloneReader* aReader) {
using namespace mozilla::dom::fs;
FileSystemEntryMetadata metadata;
if (!ConstructHandleMetadata(aCx, aReader, /* aDirectory */ true, metadata)) {
return nullptr;
}
// XXX Get the manager from Navigator!
auto fileSystemManager = MakeRefPtr<FileSystemManager>(aGlobal, nullptr);
RefPtr<FileSystemDirectoryHandle> fsHandle =
new FileSystemDirectoryHandle(aGlobal, fileSystemManager, metadata);
return fsHandle.forget();
}
// WebIDL Boilerplate
nsIGlobalObject* FileSystemHandle::GetParentObject() const { return mGlobal; }
@ -72,4 +153,53 @@ already_AddRefed<Promise> FileSystemHandle::IsSameEntry(
return promise.forget();
}
// static
already_AddRefed<FileSystemHandle> FileSystemHandle::ReadStructuredClone(
JSContext* aCx, nsIGlobalObject* aGlobal,
JSStructuredCloneReader* aReader) {
uint32_t kind = static_cast<uint32_t>(FileSystemHandleKind::EndGuard_);
if (!JS_ReadBytes(aReader, reinterpret_cast<void*>(&kind),
sizeof(uint32_t))) {
return nullptr;
}
if (kind == static_cast<uint32_t>(FileSystemHandleKind::Directory)) {
RefPtr<FileSystemHandle> result =
FileSystemHandle::ConstructDirectoryHandle(aCx, aGlobal, aReader);
return result.forget();
}
if (kind == static_cast<uint32_t>(FileSystemHandleKind::File)) {
RefPtr<FileSystemHandle> result =
FileSystemHandle::ConstructFileHandle(aCx, aGlobal, aReader);
return result.forget();
}
return nullptr;
}
bool FileSystemHandle::WriteStructuredClone(
JSContext* aCx, JSStructuredCloneWriter* aWriter) const {
auto kind = static_cast<uint32_t>(Kind());
if (NS_WARN_IF(!JS_WriteBytes(aWriter, static_cast<void*>(&kind),
sizeof(uint32_t)))) {
return false;
}
if (NS_WARN_IF(!JS_WriteBytes(
aWriter, static_cast<const void*>(mMetadata.entryId().get()),
mMetadata.entryId().Length()))) {
return false;
}
JS::Rooted<JS::Value> nameValue(aCx);
if (NS_WARN_IF(!xpc::StringToJsval(aCx, mMetadata.entryName(), &nameValue))) {
return false;
}
JS::Rooted<JSString*> name(aCx, nameValue.toString());
return JS_WriteString(aWriter, name);
}
} // namespace mozilla::dom

Просмотреть файл

@ -28,6 +28,8 @@ class ErrorResult;
namespace dom {
class FileSystemDirectoryHandle;
class FileSystemFileHandle;
enum class FileSystemHandleKind : uint8_t;
class FileSystemManager;
class FileSystemManagerChild;
@ -63,6 +65,14 @@ class FileSystemHandle : public nsISupports, public nsWrapperCache {
already_AddRefed<Promise> IsSameEntry(FileSystemHandle& aOther,
ErrorResult& aError) const;
// [Serializable] implementation
static already_AddRefed<FileSystemHandle> ReadStructuredClone(
JSContext* aCx, nsIGlobalObject* aGlobal,
JSStructuredCloneReader* aReader);
virtual bool WriteStructuredClone(JSContext* aCx,
JSStructuredCloneWriter* aWriter) const;
protected:
virtual ~FileSystemHandle() = default;
@ -73,6 +83,14 @@ class FileSystemHandle : public nsISupports, public nsWrapperCache {
const fs::FileSystemEntryMetadata mMetadata;
const UniquePtr<fs::FileSystemRequestHandler> mRequestHandler;
static already_AddRefed<FileSystemFileHandle> ConstructFileHandle(
JSContext* aCx, nsIGlobalObject* aGlobal,
JSStructuredCloneReader* aReader);
static already_AddRefed<FileSystemDirectoryHandle> ConstructDirectoryHandle(
JSContext* aCx, nsIGlobalObject* aGlobal,
JSStructuredCloneReader* aReader);
};
} // namespace dom

Просмотреть файл

@ -15,8 +15,7 @@ dictionary FileSystemRemoveOptions {
boolean recursive = false;
};
// TODO: Add Serializable
[Exposed=(Window,Worker), SecureContext, Pref="dom.fs.enabled"]
[Exposed=(Window,Worker), SecureContext, Serializable, Pref="dom.fs.enabled"]
interface FileSystemDirectoryHandle : FileSystemHandle {
async iterable<USVString, FileSystemHandle>;

Просмотреть файл

@ -7,8 +7,7 @@ dictionary FileSystemCreateWritableOptions {
boolean keepExistingData = false;
};
// TODO: Add Serializable
[Exposed=(Window,Worker), SecureContext, Pref="dom.fs.enabled"]
[Exposed=(Window,Worker), SecureContext, Serializable, Pref="dom.fs.enabled"]
interface FileSystemFileHandle : FileSystemHandle {
[NewObject]
Promise<File> getFile();

Просмотреть файл

@ -8,8 +8,7 @@ enum FileSystemHandleKind {
"directory",
};
// TODO: Add Serializable
[Exposed=(Window,Worker), SecureContext, Pref="dom.fs.enabled"]
[Exposed=(Window,Worker), SecureContext, Serializable, Pref="dom.fs.enabled"]
interface FileSystemHandle {
readonly attribute FileSystemHandleKind kind;
readonly attribute USVString name;