Bug 1265767 - Subset of Blink FileSystem API - patch 2 - Entries, r=smaug

This commit is contained in:
Andrea Marchesini 2016-06-07 00:55:16 +02:00
Родитель 1a7f4ecbd2
Коммит 5a7749a26f
17 изменённых файлов: 341 добавлений и 41 удалений

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

@ -5,13 +5,27 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "DirectoryEntry.h"
#include "mozilla/dom/Directory.h"
namespace mozilla {
namespace dom {
DirectoryEntry::DirectoryEntry(nsIGlobalObject* aGlobal)
NS_IMPL_CYCLE_COLLECTION_INHERITED(DirectoryEntry, Entry, mDirectory)
NS_IMPL_ADDREF_INHERITED(DirectoryEntry, Entry)
NS_IMPL_RELEASE_INHERITED(DirectoryEntry, Entry)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(DirectoryEntry)
NS_INTERFACE_MAP_END_INHERITING(Entry)
DirectoryEntry::DirectoryEntry(nsIGlobalObject* aGlobal,
Directory* aDirectory)
: Entry(aGlobal)
{}
, mDirectory(aDirectory)
{
MOZ_ASSERT(aGlobal);
MOZ_ASSERT(mDirectory);
}
DirectoryEntry::~DirectoryEntry()
{}
@ -22,5 +36,17 @@ DirectoryEntry::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
return DirectoryEntryBinding::Wrap(aCx, this, aGivenProto);
}
void
DirectoryEntry::GetName(nsAString& aName, ErrorResult& aRv) const
{
mDirectory->GetName(aName, aRv);
}
void
DirectoryEntry::GetFullPath(nsAString& aPath, ErrorResult& aRv) const
{
mDirectory->GetPath(aPath, aRv);
}
} // dom namespace
} // mozilla namespace

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

@ -13,14 +13,31 @@
namespace mozilla {
namespace dom {
class Directory;
class DirectoryEntry final : public Entry
{
public:
explicit DirectoryEntry(nsIGlobalObject* aGlobalObject);
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(DirectoryEntry, Entry)
DirectoryEntry(nsIGlobalObject* aGlobalObject, Directory* aDirectory);
virtual JSObject*
WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
virtual bool
IsDirectory() const override
{
return true;
}
virtual void
GetName(nsAString& aName, ErrorResult& aRv) const override;
virtual void
GetFullPath(nsAString& aFullPath, ErrorResult& aRv) const override;
already_AddRefed<DirectoryReader>
CreateReader(ErrorResult& aRv) const
{
@ -56,6 +73,8 @@ public:
private:
~DirectoryEntry();
RefPtr<Directory> mDirectory;
};
} // namespace dom

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

@ -5,6 +5,10 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "Entry.h"
#include "DirectoryEntry.h"
#include "FileEntry.h"
#include "mozilla/dom/UnionTypes.h"
namespace mozilla {
namespace dom {
@ -19,9 +23,29 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Entry)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
/* static */ already_AddRefed<Entry>
Entry::Create(nsIGlobalObject* aGlobalObject,
const OwningFileOrDirectory& aFileOrDirectory)
{
MOZ_ASSERT(aGlobalObject);
RefPtr<Entry> entry;
if (aFileOrDirectory.IsFile()) {
entry = new FileEntry(aGlobalObject, aFileOrDirectory.GetAsFile());
} else {
MOZ_ASSERT(aFileOrDirectory.IsDirectory());
entry = new DirectoryEntry(aGlobalObject,
aFileOrDirectory.GetAsDirectory());
}
return entry.forget();
}
Entry::Entry(nsIGlobalObject* aGlobal)
: mParent(aGlobal)
{}
{
MOZ_ASSERT(aGlobal);
}
Entry::~Entry()
{}

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

@ -17,6 +17,7 @@ namespace mozilla {
namespace dom {
class DOMFileSystem;
class OwningFileOrDirectory;
class Entry
: public nsISupports
@ -26,7 +27,9 @@ public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(Entry)
explicit Entry(nsIGlobalObject* aGlobalObject);
static already_AddRefed<Entry>
Create(nsIGlobalObject* aGlobalObject,
const OwningFileOrDirectory& aFileOrDirectory);
nsIGlobalObject*
GetParentObject() const
@ -37,31 +40,23 @@ public:
virtual JSObject*
WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
bool
GetIsFile(ErrorResult& aRv) const
virtual bool
IsFile() const
{
aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
return false;
}
bool
GetIsDirectory(ErrorResult& aRv) const
virtual bool
IsDirectory() const
{
aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
return false;
}
void
GetName(nsAString& aName, ErrorResult& aRv) const
{
aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
}
virtual void
GetName(nsAString& aName, ErrorResult& aRv) const = 0;
void
GetFullPath(nsAString& aFullPath, ErrorResult& aRv) const
{
aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
}
virtual void
GetFullPath(nsAString& aFullPath, ErrorResult& aRv) const = 0;
DOMFileSystem*
GetFilesystem(ErrorResult& aRv) const
@ -71,6 +66,7 @@ public:
}
protected:
Entry(nsIGlobalObject* aGlobalObject);
virtual ~Entry();
private:

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

@ -5,13 +5,27 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "FileEntry.h"
#include "mozilla/dom/File.h"
namespace mozilla {
namespace dom {
FileEntry::FileEntry(nsIGlobalObject* aGlobal)
NS_IMPL_CYCLE_COLLECTION_INHERITED(FileEntry, Entry, mFile)
NS_IMPL_ADDREF_INHERITED(FileEntry, Entry)
NS_IMPL_RELEASE_INHERITED(FileEntry, Entry)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(FileEntry)
NS_INTERFACE_MAP_END_INHERITING(Entry)
FileEntry::FileEntry(nsIGlobalObject* aGlobal,
File* aFile)
: Entry(aGlobal)
{}
, mFile(aFile)
{
MOZ_ASSERT(aGlobal);
MOZ_ASSERT(mFile);
}
FileEntry::~FileEntry()
{}
@ -22,5 +36,17 @@ FileEntry::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
return FileEntryBinding::Wrap(aCx, this, aGivenProto);
}
void
FileEntry::GetName(nsAString& aName, ErrorResult& aRv) const
{
mFile->GetName(aName);
}
void
FileEntry::GetFullPath(nsAString& aPath, ErrorResult& aRv) const
{
mFile->GetPath(aPath);
}
} // dom namespace
} // mozilla namespace

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

@ -7,23 +7,36 @@
#ifndef mozilla_dom_FileEntry_h
#define mozilla_dom_FileEntry_h
#include "mozilla/Attributes.h"
#include "mozilla/ErrorResult.h"
#include "mozilla/dom/BindingDeclarations.h"
#include "nsCycleCollectionParticipant.h"
#include "nsWrapperCache.h"
#include "mozilla/dom/Entry.h"
namespace mozilla {
namespace dom {
class File;
class FileEntry final : public Entry
{
public:
explicit FileEntry(nsIGlobalObject* aGlobalObject);
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(FileEntry, Entry)
FileEntry(nsIGlobalObject* aGlobalObject, File* aFile);
virtual JSObject*
WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
virtual bool
IsFile() const override
{
return true;
}
virtual void
GetName(nsAString& aName, ErrorResult& aRv) const override;
virtual void
GetFullPath(nsAString& aFullPath, ErrorResult& aRv) const override;
void
CreateWriter(VoidCallback& aSuccessCallback,
const Optional<OwningNonNull<ErrorCallback>>& aErrorCallback,
@ -33,15 +46,17 @@ public:
}
void
File(BlobCallback& aSuccessCallback,
const Optional<OwningNonNull<ErrorCallback>>& aErrorCallback,
ErrorResult& aRv) const
GetFile(BlobCallback& aSuccessCallback,
const Optional<OwningNonNull<ErrorCallback>>& aErrorCallback,
ErrorResult& aRv) const
{
aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
}
private:
~FileEntry();
RefPtr<File> mFile;
};
} // namespace dom

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

@ -4,6 +4,8 @@
# 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/.
TEST_DIRS += ['tests']
EXPORTS.mozilla.dom += [
'DirectoryEntry.h',
'DirectoryReader.h',

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

@ -0,0 +1,5 @@
[DEFAULT]
support-files =
script_entries.js
[test_basic.html]

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

@ -0,0 +1,7 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
MOCHITEST_MANIFESTS += ['mochitest.ini']

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

@ -0,0 +1,35 @@
var { classes: Cc, interfaces: Ci, utils: Cu } = Components;
Cu.importGlobalProperties(["File", "Directory"]);
addMessageListener("entries.open", function (e) {
var tmpFile = Cc["@mozilla.org/file/directory_service;1"]
.getService(Ci.nsIDirectoryService)
.QueryInterface(Ci.nsIProperties)
.get('TmpD', Ci.nsIFile)
tmpFile.append('file.txt');
tmpFile.createUnique(Components.interfaces.nsIFile.FILE_TYPE, 0o600);
var tmpDir = Cc["@mozilla.org/file/directory_service;1"]
.getService(Ci.nsIDirectoryService)
.QueryInterface(Ci.nsIProperties)
.get('TmpD', Ci.nsIFile)
tmpDir.append('dir-test');
tmpDir.createUnique(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0o700);
var file1 = tmpDir.clone();
file1.append('foo.txt');
file1.create(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 0o600);
var dir = tmpDir.clone();
dir.append('subdir');
dir.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0o700);
var file2 = dir.clone();
file2.append('bar.txt');
file2.create(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 0o600);
sendAsyncMessage("entries.opened", {
data: [ new Directory(tmpDir.path), new File(tmpFile) ]
});
});

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

@ -0,0 +1,97 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test for Blink FileSystem API - subset</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<input id="entries" type="file"></input>
<script type="application/javascript;version=1.7">
var fileEntry;
var directoryEntry;
function setup_tests() {
SpecialPowers.pushPrefEnv({"set": [["dom.webkitBlink.dirPicker.enabled", true],
["dom.webkitBlink.filesystem.enabled", true]]}, next);
}
function populate_entries() {
var url = SimpleTest.getTestFileURL("script_entries.js");
var script = SpecialPowers.loadChromeScript(url);
function onOpened(message) {
var entries = document.getElementById('entries');
SpecialPowers.wrap(entries).mozSetDndFilesAndDirectories(message.data);
script.destroy();
next();
}
script.addMessageListener("entries.opened", onOpened);
script.sendAsyncMessage("entries.open");
}
function test_entries() {
var entries = document.getElementById('entries');
ok("webkitEntries" in entries, "HTMLInputElement.webkitEntries");
is(entries.webkitEntries.length, 2, "HTMLInputElement.webkitEntries.length == 2");
is(entries.files.length, 1, "HTMLInputElement.files is still populated");
for (var i = 0; i < entries.webkitEntries.length; ++i) {
if (entries.webkitEntries[i].isFile) {
ok(!fileEntry, "We just want 1 fileEntry");
fileEntry = entries.webkitEntries[i];
} else {
ok(entries.webkitEntries[i].isDirectory, "If not a file, we have a directory.");
ok(!directoryEntry, "We just want 1 directoryEntry");
directoryEntry = entries.webkitEntries[i];
}
}
next();
}
function test_fileEntry() {
ok("name" in fileEntry, "We have a name.");
ok("fullPath" in fileEntry, "We have a fullPath.");
ok("filesystem" in fileEntry, "We have a filesystem.");
next();
}
function test_directoryEntry() {
ok("name" in directoryEntry, "We have a name.");
ok("fullPath" in directoryEntry, "We have a fullPath.");
ok("filesystem" in directoryEntry, "We have a filesystem.");
next();
}
var tests = [
setup_tests,
populate_entries,
test_entries,
test_fileEntry,
test_directoryEntry,
];
function next() {
if (!tests.length) {
SimpleTest.finish();
return;
}
var test = tests.shift();
test();
}
SimpleTest.waitForExplicitFinish();
next();
</script>
</body>
</html>

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

@ -79,6 +79,7 @@
#include "nsIRadioGroupContainer.h"
// input type=file
#include "mozilla/dom/Entry.h"
#include "mozilla/dom/File.h"
#include "mozilla/dom/FileList.h"
#include "nsIFile.h"
@ -1533,6 +1534,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(HTMLInputElement,
}
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFileList)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mEntries)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(HTMLInputElement,
@ -1541,6 +1543,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(HTMLInputElement,
NS_IMPL_CYCLE_COLLECTION_UNLINK(mControllers)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mFilesOrDirectories)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mFileList)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mEntries)
if (tmp->IsSingleLineTextControl(false)) {
tmp->mInputData.mState->Unlink();
}
@ -3074,6 +3077,16 @@ HTMLInputElement::SetFiles(nsIDOMFileList* aFiles,
AfterSetFilesOrDirectories(aSetValueChanged);
}
void
HTMLInputElement::MozSetDndFilesAndDirectories(const nsTArray<OwningFileOrDirectory>& aFilesOrDirectories)
{
if (Preferences::GetBool("dom.webkitBlink.filesystem.enabled", false)) {
UpdateEntries(aFilesOrDirectories);
}
SetFilesOrDirectories(aFilesOrDirectories, true);
}
void
HTMLInputElement::AfterSetFilesOrDirectories(bool aSetValueChanged)
{
@ -8183,6 +8196,30 @@ HTMLInputElement::ExploreDirectoryRecursively(bool aSetValueChanged)
helper->AddCallback(callback);
}
void
HTMLInputElement::UpdateEntries(const nsTArray<OwningFileOrDirectory>& aFilesOrDirectories)
{
mEntries.Clear();
nsCOMPtr<nsIGlobalObject> global = OwnerDoc()->GetScopeObject();
MOZ_ASSERT(global);
for (uint32_t i = 0; i < aFilesOrDirectories.Length(); ++i) {
RefPtr<Entry> entry = Entry::Create(global, aFilesOrDirectories[i]);
MOZ_ASSERT(entry);
if (!mEntries.AppendElement(entry, fallible)) {
return;
}
}
}
void
HTMLInputElement::GetWebkitEntries(nsTArray<RefPtr<Entry>>& aSequence)
{
aSequence.AppendElements(mEntries);
}
} // namespace dom
} // namespace mozilla

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

@ -238,6 +238,8 @@ public:
bool aSetValueChanged);
void SetFiles(nsIDOMFileList* aFiles, bool aSetValueChanged);
void MozSetDndFilesAndDirectories(const nsTArray<OwningFileOrDirectory>& aSequence);
// Called when a nsIFilePicker or a nsIColorPicker terminate.
void PickerClosed();
@ -716,10 +718,7 @@ public:
SetHTMLBoolAttr(nsGkAtoms::webkitdirectory, aValue, aRv);
}
void GetWebkitEntries(nsTArray<RefPtr<Entry>>& aSequence, ErrorResult& aRv)
{
aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
}
void GetWebkitEntries(nsTArray<RefPtr<Entry>>& aSequence);
bool IsFilesAndDirectoriesSupported() const;
@ -957,6 +956,8 @@ protected:
*/
void UpdateFileList();
void UpdateEntries(const nsTArray<OwningFileOrDirectory>& aFilesOrDirectories);
/**
* Called after calling one of the SetFilesOrDirectories() functions.
* This method can explore the directory recursively if needed.
@ -1334,6 +1335,7 @@ protected:
#endif
RefPtr<FileList> mFileList;
Sequence<RefPtr<Entry>> mEntries;
nsString mStaticDocFileList;

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

@ -6,10 +6,7 @@
[NoInterfaceObject]
interface Entry {
[GetterThrows]
readonly attribute boolean isFile;
[GetterThrows]
readonly attribute boolean isDirectory;
[GetterThrows]
@ -85,7 +82,7 @@ interface FileEntry : Entry {
[Throws]
void createWriter (VoidCallback successCallback, optional ErrorCallback errorCallback);
[Throws]
[Throws,BinaryName="GetFile"]
void file (BlobCallback successCallback, optional ErrorCallback errorCallback);
};

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

@ -160,6 +160,10 @@ partial interface HTMLInputElement {
[ChromeOnly, Throws]
void mozSetDirectory(DOMString directoryPath);
// This method is meant to use for testing only.
[ChromeOnly]
void mozSetDndFilesAndDirectories(sequence<(File or Directory)> list);
// Number controls (<input type=number>) have an anonymous text control
// (<input type=text>) in the anonymous shadow tree that they contain. On
// such an anonymous text control this property provides access to the
@ -222,7 +226,7 @@ HTMLInputElement implements MozPhonetic;
// Webkit/Blink
partial interface HTMLInputElement {
[Pref="dom.webkitBlink.filesystem.enabled", Cached, Constant, GetterThrows]
[Pref="dom.webkitBlink.filesystem.enabled", Cached, Constant]
readonly attribute sequence<Entry> webkitEntries;
[Pref="dom.webkitBlink.dirPicker.enabled", BinaryName="WebkitDirectoryAttr", SetterThrows]

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

@ -31,6 +31,7 @@
#include "mozilla/dom/BlobBinding.h"
#include "mozilla/dom/cache/CacheStorage.h"
#include "mozilla/dom/CSSBinding.h"
#include "mozilla/dom/DirectoryBinding.h"
#include "mozilla/dom/IndexedDatabaseManager.h"
#include "mozilla/dom/Fetch.h"
#include "mozilla/dom/FileBinding.h"
@ -909,6 +910,8 @@ xpc::GlobalProperties::Parse(JSContext* cx, JS::HandleObject obj)
btoa = true;
} else if (!strcmp(name.ptr(), "Blob")) {
Blob = true;
} else if (!strcmp(name.ptr(), "Directory")) {
Directory = true;
} else if (!strcmp(name.ptr(), "File")) {
File = true;
} else if (!strcmp(name.ptr(), "crypto")) {
@ -974,6 +977,10 @@ xpc::GlobalProperties::Define(JSContext* cx, JS::HandleObject obj)
!dom::BlobBinding::GetConstructorObject(cx, obj))
return false;
if (Directory &&
!dom::DirectoryBinding::GetConstructorObject(cx, obj))
return false;
if (File &&
!dom::FileBinding::GetConstructorObject(cx, obj))
return false;

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

@ -3333,6 +3333,7 @@ struct GlobalProperties {
bool atob : 1;
bool btoa : 1;
bool Blob : 1;
bool Directory : 1;
bool File : 1;
bool crypto : 1;
bool rtcIdentityProvider : 1;