Commit 886077da authored by Marijn Kruisselbrink's avatar Marijn Kruisselbrink Committed by Commit Bot

[NativeFS] Update async iterable API to match spec.

Matching the changes from https://github.com/WICG/native-file-system/pull/177
Since the bindings layer doesn't support async iterables yet, this CL
does this in a bit of a hacky way, that isn't entirely web-idl
compliant. It is much closer to the desired API than what we had though,
so seems an improvement until bindings properly support async iterables.

Bug: 1011539, 1087157
Change-Id: I2eb0a3b1d6383149b769a9961bf890eaf6956b2b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2248414Reviewed-by: default avatarTrent Apted <tapted@chromium.org>
Reviewed-by: default avatarYuki Shiino <yukishiino@chromium.org>
Commit-Queue: Marijn Kruisselbrink <mek@chromium.org>
Cr-Commit-Position: refs/heads/master@{#790486}
parent 87b556b1
......@@ -720,9 +720,9 @@ IN_PROC_BROWSER_TEST_P(
web_contents,
"(async function() {"
" let fileNames = [];"
" const files = await window.launchParams.files[0].getEntries();"
" for await (const f of files)"
" fileNames.push(f.name);"
" const files = await window.launchParams.files[0].keys();"
" for await (const name of files)"
" fileNames.push(name);"
" domAutomationController.send(fileNames.sort().join(';'));"
"})();",
&file_names));
......
......@@ -532,7 +532,7 @@ async function processOtherFilesInDirectory(
const relatedFiles = [];
// TODO(b/158149714): Clear out old tokens as well? Care needs to be taken to
// ensure any file currently open with unsaved changes can still be saved.
for await (const /** !FileSystemHandle */ handle of directory.getEntries()) {
for await (const /** !FileSystemHandle */ handle of directory.values()) {
if (localLaunchNumber !== globalLaunchNumber) {
// Abort, another more up to date launch in progress.
return ProcessOtherFilesResult.ABORT;
......@@ -565,7 +565,7 @@ async function processOtherFilesInDirectory(
return ProcessOtherFilesResult.ABORT;
}
// Iteration order is not guaranteed using `directory.getEntries()`, so we
// Iteration order is not guaranteed using `directory.entries()`, so we
// sort it afterwards by modification time to ensure a consistent and logical
// order. More recent (i.e. higher timestamp) files should appear first.
relatedFiles.sort((a, b) => {
......
......@@ -140,8 +140,12 @@ class FileSystemDirectoryHandle extends FileSystemHandle {
*/
getDirectoryHandle(name, options) {}
/** @return {!AsyncIterable<!Array<string|!FileSystemHandle>>} */
entries() {}
/** @return {!AsyncIterable<string>} */
keys() {}
/** @return {!AsyncIterable<!FileSystemHandle>} */
getEntries() {}
values() {}
/**
* @param {string} name
......
......@@ -216,13 +216,35 @@ class FakeFileSystemDirectoryHandle extends FakeFileSystemHandle {
}
/** @override */
getDirectoryHandle(name, options) {}
/**
* @override
* @return {!AsyncIterable<!Array<string|!FileSystemHandle>>}
* @suppress {reportUnknownTypes} suppress [JSC_UNKNOWN_EXPR_TYPE] for `yield
* [file.name, file]`.
*/
async * entries() {
for (const file of this.files) {
yield [file.name, file];
}
}
/**
* @override
* @return {!AsyncIterable<string>}
* @suppress {reportUnknownTypes} suppress [JSC_UNKNOWN_EXPR_TYPE] for `yield
* file.name`.
*/
async * keys() {
for (const file of this.files) {
yield file.name;
}
}
/**
* @override
* @return {!AsyncIterable<!FileSystemHandle>}
* @suppress {reportUnknownTypes} suppress [JSC_UNKNOWN_EXPR_TYPE] for `yield
* file`.
*/
async * getEntries() {
async * values() {
for (const file of this.files) {
yield file;
}
......
......@@ -381,7 +381,6 @@ static_idl_files_in_modules = get_path_info(
"//third_party/blink/renderer/modules/native_file_system/file_system_writable_file_stream.idl",
"//third_party/blink/renderer/modules/native_file_system/get_system_directory_options.idl",
"//third_party/blink/renderer/modules/native_file_system/native_file_system_directory_iterator.idl",
"//third_party/blink/renderer/modules/native_file_system/native_file_system_directory_iterator_entry.idl",
"//third_party/blink/renderer/modules/native_file_system/open_file_picker_options.idl",
"//third_party/blink/renderer/modules/native_file_system/save_file_picker_options.idl",
"//third_party/blink/renderer/modules/native_file_system/window_native_file_system.idl",
......
......@@ -529,6 +529,26 @@ static void Install{{v8_class}}Template(
{% endfilter %}
{% endif %}
{% if interface_name == 'FileSystemDirectoryHandle' %}
// Temporary @@asyncIterator support for FileSystemDirectoryHandle
// TODO(https://crbug.com/1087157): Replace with proper bindings support.
static const V8DOMConfiguration::SymbolKeyedMethodConfiguration
kSymbolKeyedIteratorConfiguration = {
v8::Symbol::GetAsyncIterator,
"entries",
V8FileSystemDirectoryHandle::EntriesMethodCallback,
0,
v8::DontEnum,
V8DOMConfiguration::kOnPrototype,
V8DOMConfiguration::kCheckHolder,
V8DOMConfiguration::kDoNotCheckAccess,
V8DOMConfiguration::kHasSideEffect
};
V8DOMConfiguration::InstallMethod(
isolate, world, prototype_template, signature,
kSymbolKeyedIteratorConfiguration);
{% endif %}
{% if interface_name == 'Iterator' %}
// The WebIDL spec says when an interface has pair iterators the iterators it
// returns must be instances of the "default iterator object" whose
......@@ -566,6 +586,17 @@ static void Install{{v8_class}}Template(
interface_template->Inherit(intrinsic_iterator_prototype_interface_template);
{% endif %}
{% if interface_name == 'NativeFileSystemDirectoryIterator' %}
// Temporary @@asyncIterator support for FileSystemDirectoryHandle
// TODO(https://crbug.com/1087157): Replace with proper bindings support.
v8::Local<v8::FunctionTemplate> intrinsic_iterator_prototype_interface_template =
v8::FunctionTemplate::New(isolate);
intrinsic_iterator_prototype_interface_template->RemovePrototype();
intrinsic_iterator_prototype_interface_template->SetIntrinsicDataProperty(
V8AtomicString(isolate, "prototype"), v8::kAsyncIteratorPrototype);
interface_template->Inherit(intrinsic_iterator_prototype_interface_template);
{% endif %}
{% if interface_name == 'DOMException' %}
// The WebIDL spec states that DOMException objects have a few peculiarities.
// One of them is similar to what it mandates for Iterator objects when it
......
......@@ -10,6 +10,14 @@
RuntimeEnabled=NativeFileSystem,
ImplementedAs=NativeFileSystemDirectoryHandle
] interface FileSystemDirectoryHandle : FileSystemHandle {
// TODO(https://crbug.com/1087157): This interface defines an async
// iterable, however that isn't supported yet by the bindings. So for now
// just explicitly define what an async iterable definition implies.
//async iterable<USVString, FileSystemHandle>;
NativeFileSystemDirectoryIterator entries();
NativeFileSystemDirectoryIterator keys();
NativeFileSystemDirectoryIterator values();
[CallWith=ScriptState, RuntimeEnabled=LegacyNativeFileSystem, ImplementedAs=getFileHandle]
Promise<FileSystemFileHandle> getFile(USVString name, optional FileSystemGetFileOptions options = {});
[CallWith=ScriptState, RuntimeEnabled=LegacyNativeFileSystem, ImplementedAs=getDirectoryHandle]
......@@ -18,7 +26,7 @@
[CallWith=ScriptState] Promise<FileSystemFileHandle> getFileHandle(USVString name, optional FileSystemGetFileOptions options = {});
[CallWith=ScriptState] Promise<FileSystemDirectoryHandle> getDirectoryHandle(USVString name, optional FileSystemGetDirectoryOptions options = {});
[CallWith=ScriptState] object getEntries();
[CallWith=ScriptState, RuntimeEnabled=LegacyNativeFileSystem] object getEntries();
[CallWith=ScriptState] Promise<void> removeEntry(USVString name, optional FileSystemRemoveOptions options = {});
......
......@@ -23,7 +23,6 @@ modules_dictionary_idl_files = [
"file_system_remove_options.idl",
"get_system_directory_options.idl",
"open_file_picker_options.idl",
"native_file_system_directory_iterator_entry.idl",
"save_file_picker_options.idl",
"write_params.idl",
]
......
......@@ -12,6 +12,7 @@
#include "third_party/blink/public/mojom/native_file_system/native_file_system_manager.mojom-blink.h"
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_file_system_directory_handle.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_file_system_get_directory_options.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_file_system_get_file_options.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_file_system_remove_options.h"
......@@ -43,6 +44,24 @@ NativeFileSystemDirectoryHandle::NativeFileSystemDirectoryHandle(
DCHECK(mojo_ptr_.is_bound());
}
NativeFileSystemDirectoryIterator* NativeFileSystemDirectoryHandle::entries() {
return MakeGarbageCollected<NativeFileSystemDirectoryIterator>(
this, NativeFileSystemDirectoryIterator::Mode::kKeyValue,
GetExecutionContext());
}
NativeFileSystemDirectoryIterator* NativeFileSystemDirectoryHandle::keys() {
return MakeGarbageCollected<NativeFileSystemDirectoryIterator>(
this, NativeFileSystemDirectoryIterator::Mode::kKey,
GetExecutionContext());
}
NativeFileSystemDirectoryIterator* NativeFileSystemDirectoryHandle::values() {
return MakeGarbageCollected<NativeFileSystemDirectoryIterator>(
this, NativeFileSystemDirectoryIterator::Mode::kValue,
GetExecutionContext());
}
ScriptPromise NativeFileSystemDirectoryHandle::getFileHandle(
ScriptState* script_state,
const String& name,
......@@ -119,7 +138,8 @@ void ReturnDataFunction(const v8::FunctionCallbackInfo<v8::Value>& info) {
ScriptValue NativeFileSystemDirectoryHandle::getEntries(
ScriptState* script_state) {
auto* iterator = MakeGarbageCollected<NativeFileSystemDirectoryIterator>(
this, ExecutionContext::From(script_state));
this, NativeFileSystemDirectoryIterator::Mode::kValue,
ExecutionContext::From(script_state));
auto* isolate = script_state->GetIsolate();
auto context = script_state->GetContext();
v8::Local<v8::Object> result = v8::Object::New(isolate);
......
......@@ -15,6 +15,7 @@ class FileSystemGetDirectoryOptions;
class FileSystemGetFileOptions;
class FileSystemRemoveOptions;
class GetSystemDirectoryOptions;
class NativeFileSystemDirectoryIterator;
class NativeFileSystemDirectoryHandle final : public NativeFileSystemHandle {
DEFINE_WRAPPERTYPEINFO();
......@@ -25,6 +26,11 @@ class NativeFileSystemDirectoryHandle final : public NativeFileSystemHandle {
const String& name,
mojo::PendingRemote<mojom::blink::NativeFileSystemDirectoryHandle>);
// FileSystemDirectoryHandle IDL interface:
NativeFileSystemDirectoryIterator* entries();
NativeFileSystemDirectoryIterator* keys();
NativeFileSystemDirectoryIterator* values();
bool isDirectory() const override { return true; }
ScriptPromise getFileHandle(ScriptState*,
......
......@@ -4,8 +4,9 @@
#include "third_party/blink/renderer/modules/native_file_system/native_file_system_directory_iterator.h"
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_native_file_system_directory_iterator_entry.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_iterator_result_value.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/core/fileapi/file_error.h"
#include "third_party/blink/renderer/modules/native_file_system/native_file_system_directory_handle.h"
......@@ -17,8 +18,10 @@ namespace blink {
NativeFileSystemDirectoryIterator::NativeFileSystemDirectoryIterator(
NativeFileSystemDirectoryHandle* directory,
Mode mode,
ExecutionContext* execution_context)
: ExecutionContextClient(execution_context),
mode_(mode),
directory_(directory),
receiver_(this, execution_context) {
directory_->MojoHandle()->GetEntries(receiver_.BindNewPipeAndPassRemote(
......@@ -35,10 +38,25 @@ ScriptPromise NativeFileSystemDirectoryIterator::next(
}
if (!entries_.IsEmpty()) {
NativeFileSystemDirectoryIteratorEntry* result =
NativeFileSystemDirectoryIteratorEntry::Create();
result->setValue(entries_.TakeFirst());
return ScriptPromise::Cast(script_state, ToV8(result, script_state));
NativeFileSystemHandle* handle = entries_.TakeFirst();
ScriptValue result;
switch (mode_) {
case Mode::kKey:
result = V8IteratorResult(script_state, handle->name());
break;
case Mode::kValue:
result = V8IteratorResult(script_state, handle);
break;
case Mode::kKeyValue:
HeapVector<ScriptValue, 2> keyvalue;
keyvalue.push_back(ScriptValue(script_state->GetIsolate(),
ToV8(handle->name(), script_state)));
keyvalue.push_back(ScriptValue(script_state->GetIsolate(),
ToV8(handle, script_state)));
result = V8IteratorResult(script_state, keyvalue);
break;
}
return ScriptPromise::Cast(script_state, result);
}
if (waiting_for_more_entries_) {
......@@ -47,10 +65,7 @@ ScriptPromise NativeFileSystemDirectoryIterator::next(
return pending_next_->Promise();
}
NativeFileSystemDirectoryIteratorEntry* result =
NativeFileSystemDirectoryIteratorEntry::Create();
result->setDone(true);
return ScriptPromise::Cast(script_state, ToV8(result, script_state));
return ScriptPromise::Cast(script_state, V8IteratorResultDone(script_state));
}
void NativeFileSystemDirectoryIterator::Trace(Visitor* visitor) const {
......
......@@ -28,7 +28,11 @@ class NativeFileSystemDirectoryIterator final
USING_GARBAGE_COLLECTED_MIXIN(NativeFileSystemDirectoryIterator);
public:
// Should this iterator returns keys, values or both?
enum Mode { kKey, kValue, kKeyValue };
NativeFileSystemDirectoryIterator(NativeFileSystemDirectoryHandle* directory,
Mode mode,
ExecutionContext* execution_context);
ScriptPromise next(ScriptState*);
......@@ -40,6 +44,7 @@ class NativeFileSystemDirectoryIterator final
Vector<mojom::blink::NativeFileSystemEntryPtr> entries,
bool has_more_entries) override;
Mode mode_;
mojom::blink::NativeFileSystemErrorPtr error_;
bool waiting_for_more_entries_ = true;
HeapDeque<Member<NativeFileSystemHandle>> entries_;
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Used by NativeFileSystemDirectoryIterator to represents results of next() calls.
// https://github.com/WICG/writable-files/blob/master/EXPLAINER.md
// https://www.ecma-international.org/ecma-262/9.0/index.html#sec-iteratorresult-interface
dictionary NativeFileSystemDirectoryIteratorEntry {
FileSystemHandle value;
boolean done = false;
};
......@@ -39,7 +39,7 @@ PASS FileSystemDirectoryHandle interface object name
PASS FileSystemDirectoryHandle interface: existence and properties of interface prototype object
PASS FileSystemDirectoryHandle interface: existence and properties of interface prototype object's "constructor" property
PASS FileSystemDirectoryHandle interface: existence and properties of interface prototype object's @@unscopables property
FAIL FileSystemDirectoryHandle interface: async iterable<USVString, FileSystemHandle> Cannot read property 'writable' of undefined
FAIL FileSystemDirectoryHandle interface: async iterable<USVString, FileSystemHandle> assert_equals: entries method should be the same as @@asyncIterator method expected function "function entries() { [native code] }" but got function "function entries() { [native code] }"
PASS FileSystemDirectoryHandle interface: operation getFileHandle(USVString, optional FileSystemGetFileOptions)
PASS FileSystemDirectoryHandle interface: operation getDirectoryHandle(USVString, optional FileSystemGetDirectoryOptions)
PASS FileSystemDirectoryHandle interface: operation removeEntry(USVString, optional FileSystemRemoveOptions)
......
......@@ -39,7 +39,7 @@ PASS FileSystemDirectoryHandle interface object name
PASS FileSystemDirectoryHandle interface: existence and properties of interface prototype object
PASS FileSystemDirectoryHandle interface: existence and properties of interface prototype object's "constructor" property
PASS FileSystemDirectoryHandle interface: existence and properties of interface prototype object's @@unscopables property
FAIL FileSystemDirectoryHandle interface: async iterable<USVString, FileSystemHandle> Cannot read property 'writable' of undefined
FAIL FileSystemDirectoryHandle interface: async iterable<USVString, FileSystemHandle> assert_equals: entries method should be the same as @@asyncIterator method expected function "function entries() { [native code] }" but got function "function entries() { [native code] }"
PASS FileSystemDirectoryHandle interface: operation getFileHandle(USVString, optional FileSystemGetFileOptions)
PASS FileSystemDirectoryHandle interface: operation getDirectoryHandle(USVString, optional FileSystemGetDirectoryOptions)
PASS FileSystemDirectoryHandle interface: operation removeEntry(USVString, optional FileSystemRemoveOptions)
......
......@@ -7,4 +7,4 @@
<script src="/resources/testdriver-vendor.js"></script>
<script src="resources/test-helpers.js"></script>
<script src="resources/native-fs-test-helpers.js"></script>
<script src="script-tests/FileSystemDirectoryHandle-getEntries.js"></script>
<script src="script-tests/FileSystemDirectoryHandle-iteration.js"></script>
......@@ -77,7 +77,7 @@ async function serialize_file_system_directory_handle(directory_handle) {
// Serialize the contents of the directory.
const serialized_files = [];
const serialized_directories = [];
for await (const child_handle of directory_handle.getEntries()) {
for await (const child_handle of directory_handle.values()) {
const serialized_child_handle = await serialize_handle(child_handle);
if (child_handle.kind === "directory") {
serialized_directories.push(serialized_child_handle);
......
......@@ -21,7 +21,7 @@ const directory_promise = (async () => {
const entries = await self.showDirectoryPicker();
assert_true(entries instanceof FileSystemHandle);
assert_true(entries instanceof FileSystemDirectoryHandle);
for await (const entry of entries.getEntries()) {
for await (const entry of entries) {
assert_unreached('Selected directory is not empty');
}
return entries;
......@@ -32,7 +32,7 @@ function directory_test(func, description) {
const directory = await directory_promise;
// To be resilient against tests not cleaning up properly, cleanup before
// every test.
for await (let entry of directory.getEntries()) {
for await (let entry of directory.values()) {
await directory.removeEntry(
entry.name, {recursive: entry.kind === 'directory'});
}
......
......@@ -9,7 +9,7 @@
async function cleanupSandboxedFileSystem() {
const dir =
await self.getOriginPrivateDirectory();
for await (let entry of dir.getEntries())
for await (let entry of dir.values())
await dir.removeEntry(entry.name, {recursive: entry.kind === 'directory'});
}
......
......@@ -25,7 +25,7 @@ async function getFileContents(handle) {
async function getDirectoryEntryCount(handle) {
let result = 0;
for await (let entry of handle.getEntries()) {
for await (let entry of handle) {
result++;
}
return result;
......@@ -33,7 +33,7 @@ async function getDirectoryEntryCount(handle) {
async function getSortedDirectoryEntries(handle) {
let result = [];
for await (let entry of handle.getEntries()) {
for await (let entry of handle.values()) {
if (entry.kind === 'directory')
result.push(entry.name + '/');
else
......
// META: script=resources/test-helpers.js
// META: script=resources/sandboxed-fs-test-helpers.js
// META: script=script-tests/FileSystemDirectoryHandle-getEntries.js
// META: script=script-tests/FileSystemDirectoryHandle-iteration.js
directory_test(async (t, root) => {
const file_name1 = 'foo1.txt';
const file_name2 = 'foo2.txt';
await createFileWithContents(t, file_name1, 'contents', /*parent=*/ root);
await createFileWithContents(t, file_name2, 'contents', /*parent=*/ root);
let abortIter = async (dir) => {
for await (let entry of dir.getEntries()) {
return entry.name;
}
};
try {
await abortIter(root);
} catch(e) {
assert_unreached('Error thrown on iteration abort.');
}
}, 'getEntries(): returning early from an iteration works');
directory_test(async (t, root) => {
const file_name1 = 'foo1.txt';
const file_name2 = 'foo2.txt';
await createFileWithContents(t, file_name1, 'contents', /*parent=*/ root);
await createFileWithContents(t, file_name2, 'contents', /*parent=*/ root);
let fullIter = async (dir) => {
let name;
for await (let entry of dir.getEntries()) {
name = entry.name;
}
return name;
};
try {
await fullIter(root);
} catch(e) {
assert_unreached('Error thrown on iteration.');
}
}, 'getEntries(): full iteration works');
directory_test(async (t, root) => {
const file_name1 = 'foo1.txt';
const file_name2 = 'foo2.txt';
await createFileWithContents(t, file_name1, 'contents', /*parent=*/ root);
await createFileWithContents(t, file_name2, 'contents', /*parent=*/ root);
for await (let entry of root) {
break;
}
}, 'returning early from an iteration doesn\'t crash');
directory_test(async (t, root) => {
const file_name1 = 'foo1.txt';
const file_name2 = 'foo2.txt';
await createFileWithContents(t, file_name1, 'contents', /*parent=*/ root);
await createFileWithContents(t, file_name2, 'contents', /*parent=*/ root);
let names = [];
for await (let entry of root) {
assert_true(Array.isArray(entry));
assert_equals(entry.length, 2);
assert_equals(typeof entry[0], 'string');
assert_true(entry[1] instanceof FileSystemFileHandle);
assert_equals(entry[0], entry[1].name);
names.push(entry[0]);
}
names.sort();
assert_array_equals(names, [file_name1, file_name2]);
}, '@@asyncIterator: full iteration works');
directory_test(async (t, root) => {
const file_name1 = 'foo1.txt';
const file_name2 = 'foo2.txt';
await createFileWithContents(t, file_name1, 'contents', /*parent=*/ root);
await createFileWithContents(t, file_name2, 'contents', /*parent=*/ root);
let names = [];
for await (let entry of root.entries()) {
assert_true(Array.isArray(entry));
assert_equals(entry.length, 2);
assert_equals(typeof entry[0], 'string');
assert_true(entry[1] instanceof FileSystemFileHandle);
assert_equals(entry[0], entry[1].name);
names.push(entry[0]);
}
names.sort();
assert_array_equals(names, [file_name1, file_name2]);
}, 'entries: full iteration works');
directory_test(async (t, root) => {
const file_name1 = 'foo1.txt';
const file_name2 = 'foo2.txt';
await createFileWithContents(t, file_name1, 'contents', /*parent=*/ root);
await createFileWithContents(t, file_name2, 'contents', /*parent=*/ root);
let names = [];
for await (let entry of root.values()) {
assert_true(entry instanceof FileSystemFileHandle);
names.push(entry.name);
}
names.sort();
assert_array_equals(names, [file_name1, file_name2]);
}, 'values: full iteration works');
directory_test(async (t, root) => {
const file_name1 = 'foo1.txt';
const file_name2 = 'foo2.txt';
await createFileWithContents(t, file_name1, 'contents', /*parent=*/ root);
await createFileWithContents(t, file_name2, 'contents', /*parent=*/ root);
let names = [];
for await (let entry of root.keys()) {
assert_equals(typeof entry, 'string');
names.push(entry);
}
names.sort();
assert_array_equals(names, [file_name1, file_name2]);
}, 'keys: full iteration works');
......@@ -13,7 +13,7 @@ test(t => {
OriginTrialsHelper.check_properties_exist(this, {
'FileSystemHandle': ['kind', 'name', 'queryPermission', 'requestPermission'],
'FileSystemFileHandle': ['getFile', 'createWritable'],
'FileSystemDirectoryHandle': ['getFileHandle', 'getDirectoryHandle', 'getEntries', 'removeEntry'],
'FileSystemDirectoryHandle': ['getFileHandle', 'getDirectoryHandle', 'entries', 'removeEntry'],
'FileSystemWritableFileStream': ['write', 'truncate', 'close', 'seek'],
'global': ['showOpenFilePicker', 'showSaveFilePicker', 'showDirectoryPicker', 'getOriginPrivateDirectory'],
});
......
......@@ -559,12 +559,15 @@ interface FileReader : EventTarget
setter onprogress
interface FileSystemDirectoryHandle : FileSystemHandle
attribute @@toStringTag
method @@asyncIterator
method constructor
method entries
method getDirectoryHandle
method getEntries
method getFileHandle
method keys
method removeEntry
method resolve
method values
interface FileSystemFileHandle : FileSystemHandle
attribute @@toStringTag
method constructor
......
......@@ -87,6 +87,7 @@ function isWebIDLConstructor(propertyKey) {
}
var wellKnownSymbols = new Map([
[Symbol.asyncIterator, "@@asyncIterator"],
[Symbol.hasInstance, "@@hasInstance"],
[Symbol.isConcatSpreadable, "@@isConcatSpreadable"],
[Symbol.iterator, "@@iterator"],
......
......@@ -494,12 +494,15 @@ Starting worker: resources/global-interface-listing-worker.js
[Worker] method readAsText
[Worker] interface FileSystemDirectoryHandle : FileSystemHandle
[Worker] attribute @@toStringTag
[Worker] method @@asyncIterator
[Worker] method constructor
[Worker] method entries
[Worker] method getDirectoryHandle
[Worker] method getEntries
[Worker] method getFileHandle
[Worker] method keys
[Worker] method removeEntry
[Worker] method resolve
[Worker] method values
[Worker] interface FileSystemFileHandle : FileSystemHandle
[Worker] attribute @@toStringTag
[Worker] method constructor
......
......@@ -2445,12 +2445,15 @@ interface FileReader : EventTarget
setter onprogress
interface FileSystemDirectoryHandle : FileSystemHandle
attribute @@toStringTag
method @@asyncIterator
method constructor
method entries
method getDirectoryHandle
method getEntries
method getFileHandle
method keys
method removeEntry
method resolve
method values
interface FileSystemFileHandle : FileSystemHandle
attribute @@toStringTag
method constructor
......
......@@ -489,12 +489,15 @@ Starting worker: resources/global-interface-listing-worker.js
[Worker] method readAsText
[Worker] interface FileSystemDirectoryHandle : FileSystemHandle
[Worker] attribute @@toStringTag
[Worker] method @@asyncIterator
[Worker] method constructor
[Worker] method entries
[Worker] method getDirectoryHandle
[Worker] method getEntries
[Worker] method getFileHandle
[Worker] method keys
[Worker] method removeEntry
[Worker] method resolve
[Worker] method values
[Worker] interface FileSystemFileHandle : FileSystemHandle
[Worker] attribute @@toStringTag
[Worker] method constructor
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment