Re: [w3c/FileAPI] Make the FileList interface iterable (#94)

I've been up all night trying to figure out the answer to 2 questions:

1. By spec, can a `FileList` instance be iterated using `for…of` and spread with `...` syntax?
2. What browsers support doing that?

I can't find a confident answer to either question.

The Google Closure compiler team thinks the spec says `FileList` is not iterable:

https://github.com/google/closure-compiler/issues/3231#issuecomment-463011621


Are they wrong?

The spec for the `FileList` interface doesn't say it's iterable in the IDL:

> ```idl
> [Exposed=(Window,Worker), Serializable]
> interface FileList {
>   getter File? item(unsigned long index);
>   readonly attribute unsigned long length;
> };
>```
> — https://www.w3.org/TR/FileAPI/#filelist-section


Yet, for contrast the the spec for `NodeList` explicitly says it's iterable:

> ```idl
> [Exposed=Window]
> interface NodeList {
>   getter Node? item(unsigned long index);
>   readonly attribute unsigned long length;
>   iterable<Node>;
> };
> ```
> — https://dom.spec.whatwg.org/#interface-nodelist


Why the difference? Both are often referred to as "array-like".

Side note: I've gone around in circles trying to figure out the meaning of the term "array-like", and have come to the conclusion it's a useless term because it's been in use since before iterators were a thing, and it's hard to tell if it's being used to describe an object with only integer index and `length` properties, or also with `[Symbol.iterator]() {` so it can be spreadable with `...` and iterated with `for…of`. It took me a while to figure out `for…of` is only intended to work with iterables, and not legacy "array-like" objects.

I tried this in Node.js and Safari and it bombs:

```js
for (const item of {
  0: 'a',
  1: 'b',
  2: 'c',
  length: 3,
})
  console.log(item);
```

@inexorabletash 

> Since FileList has an indexed property getter and an integer-typed length attribute it is implicitly iterable. No need for an explicit declaration in the spec.

You seem to say only integer index and `length` properties are required to make an object iterable (which I interpret to mean spreadable and loopable via `for…of`). As I mentioned above, I don't think this is true. But then you go on to say:

> In Chrome `!!FileList.prototype[Symbol.iterator]` is true. If other browsers don't support that it's a bug in their bindings implementation.

What justification do you have to say it would be a bug? Where does the spec say `FileList` is iterable?

If the most popular browsers (i.e. Chrome) are making `FileList` iterable via `[Symbol.iterator]() {`, then should the spec be changed to align with implementations and developer expectations?

There is no caniuse.com entry for `FileList` `@@iterator` support:

https://caniuse.com/?search=FileList


So, I've messaged friends and family to try testing this codepen out with browsers matched by this browserslist query:

https://codepen.io/jaydenseric/pen/BaWOWQj?editors=1011


```
> 0.5%, not OperaMini all, not IE > 0, not dead
```

My motivation for all these questions is that as part of the next major [`extract-files`](https://github.com/jaydenseric/extract-files) (> 1.7 million installs per week) release, I intend to iterate both normal arrays and `FileList` instances via the same `for…of` loop.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/w3c/FileAPI/issues/94#issuecomment-858653535

Received on Thursday, 10 June 2021 14:11:08 UTC