[Bug 23682] Fix the current [ArrayClass], [] and sequence<T> mess

https://www.w3.org/Bugs/Public/show_bug.cgi?id=23682

--- Comment #12 from Jonas Sicking <jonas@sicking.cc> ---
Regarding scenario D, i.e. things like HTMLInputElement.files, there appears to
be at least three decent solutions (though no great solutions).

1) Make the getter return a plain mutable JS-Array. Authors can add blobs
   to this array using normal Array mutator functions. The browser uses
   Object.observe (or Array.Observe) to update the UI.

   Also let the property have a setter. If the setter is called with a
   normal JS Array, i.e. Array.isArray() tests true, then the getter starts
   returning this Array. (Alternatively, we could treat Arrays like other
   iterables, see below)

   If the setter is called with any other type of iterable object, a new
   Array instance is created and populated with the values from this
   iterable.

   If the setter is called with something that isn't iterable, it throws.

   When the user modifies the list of attached files/blobs using the UI,
   this clears the contents of the Array and then populates it with the new
   list of files/blobs.

   This means that both of the following works:
   element.files = [blob1, blob2];
   element.files.push(blob2);

   The UA will ignore any non-Blob values in the Array. That means that any
   form submissions, and created FormData objects, as well as the UI will
   simply ignore any non-Blob values in the Array.

2) Make the getter return a plain mutable JS-Array. Authors can add blobs
   to this array using normal Array mutator functions. The browser uses
   Object.observe (or Array.Observe) to update the UI.

   The property does not have a setter at all.

   When the user modifies the list of attached files/blobs using the UI,
   this clears the contents of the Array and then populates it with the new
   list of files/blobs.

   This means that the following works
   element.files.push(blob2);

   But this doesn't
   element.files = [blob1, blob2];

   The UA will ignore any non-Blob values in the Array. That means that any
   form submissions, and created FormData objects, as well as the UI will
   simply ignore any non-Blob values in the Array.

3) Make the getter always return a frozen JS-Array. Authors can thus not
   modify this array directly.

   However the property has a setter. When called, it throws if the value
   is not an iterable.

   The setter always creates a new JS-Array and populates it with the
   values from the iterable. We may or may not skip any non-Blob values. We
   could even throw if any non-Blob values are present.

   When the user modifies the list of attached files/blobs using the UI,
   this creates a new Array instance populated with the new list of blobs,
   and then freezes it.

   The UI only needs to be updated from the setter.

   This means that the following works
   element.files = [blob1, blob2];

   But this doesn't
   element.files.push(blob2);



I could personally live with any of these three solutions.

Solution 1 is the most flexible, but also the most complex. It requires code
that want to monitor the list of files both look for the "change" event as well
as use Object.observe to observe the Array.

Solution 2 has medium complexity but has the advantage that normal array
mutations will just work. Code that want to monitor the list of files only need
to use Object.observe to observe the Array. It also means that the array
instance can be passed around and will always represent a up-to-date version of
files. (Though does that mean that it has some of the disadvantages of "live"
arrays? No more than option 1, but maybe more than option 3)

Solution 3 is the simplest one. It means that D looks a lot like B. Code that
wants to monitor the list of files only need to listen to the "change" event.
But it's also restricted in the array mutators can't be used at all and instead
requires code like:
element.files = element.files.concat(blob2);
element.files = element.files.filter((v, i) => i != 3);

Another thing to keep in mind here is that so far the only instance of use-case
D that we have in the DOM today is HTMLInputElement.files. So even if we end up
going with "the wrong" solution it's not a big deal for now.

-- 
You are receiving this mail because:
You are on the CC list for the bug.

Received on Sunday, 28 September 2014 22:31:05 UTC