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

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

            Bug ID: 23682
           Summary: Fix the current [ArrayClass], [] and sequence<T> mess
           Product: WebAppsWG
           Version: unspecified
          Hardware: PC
                OS: All
            Status: NEW
          Severity: normal
          Priority: P2
         Component: WebIDL
          Assignee: cam@mcc.id.au
          Reporter: jonas@sicking.cc
        QA Contact: public-webapps-bugzilla@w3.org
                CC: mike@w3.org, public-script-coord@w3.org

Rather than making various DOM classes be more array-like by using [ArrayClass]
we should simply use normal JS Arrays.

As far as I can tell, the use cases that we currently have for array-likes are:

A) Read-only properties returning read-only arrays which never changes for the
lifetime of the array. Example: MessageEvent.ports

B) Read-only properties returning read-only arrays which on occasion the
platform needs to change, but which the website should not be able to change.
Example: Navigator.gamepads

C) Read-only properties and functions returning "live" arrays defined in
existing APIs which on occasion the platform needs to change, but which the
website must not be able to change. Example: Node.childNodes, Window.frames

D) Mutable properties returning arrays that both the website and the platform
is able to change. Examples: HTMLInputElement.files

E) Functions accepting an array-like thing as an argument. Example:
IDBObjectStore.createIndex()

F) Functions returning an array-like thing as a result. Example:
Element.getClientRects()


For A I think we can and should simply return a frozen JS Array.

For B we often aim to return an object and then update that object whenever the
result needs to change. However this is what a "live" list is. And it's
something that has been very consistently frowned upon by web developers as
confusing.

Instead I suggest that we return a frozen JS Array. Whenever we need to change
value we drop the reference to the old array, create a new Array which contains
the new result set, and freeze this array. The resulting object is what we'll
return until the value needs to change again.

For C I think we're forced due to web compat constraints to use a custom DOM
class. However the only examples of this that I can think of is NodeList,
HTMLCollection and WindowProxy. So we could special-case these. And again,
these represent "live" lists which are generally frowned upon. So it's not
something we should encourage using WebIDL syntax like [ArrayClass].

For D I don't have a great answer. As far as I can see, the best current option
is to simply return a plain JS Array which the webpage can freely modify. And
which we modify as needed. We would also allow the website to set the property
to any iterable object. We would at that time iterate the object and construct
a new JS Array containing the iterated items.

The main downsides with this solutions is
* We can't enforce that someone doesn't stick data of the wrong type into the
Array.
* The code |x.files = myIterable; x.files === myIterable;| would return false
as x.files would return a equivalent set, not the same container object.
However this is a requirement if we want x.files.push(myFile) to consistently
work since not all iterables have a .push() function.

Potentially we could simply disallow this type of API. It's confusing anyway
for both the website and the platform to be mutating the same array. Or we just
live with the above downsides until JS grows a way to do typed arrays.

For E we should simply accept an iterable object. Probably need to define on a
per-API basis if data of the wrong type inside the array is ignored or if it
causes a TypeError exception.

For F we should return plain JS Array objects. We might want to enable both
returning new Array objects each call, and behaving like B and return the same
frozen JS Array until the return value needs to change, in which case we return
a new frozen JS Array.


The syntax I propose for this is below. This is very much an early draft and
not very polished. The important part is the behavior described above, not the
syntax described below. And it would be nice to use "array" or "iterable"
rather than "sequence".

A) [SameObject] readonly attribute sequence<MessagePort> ports;

B) readonly attribute sequence<Gamepad> gamepads;

C) readonly attribute NodeList childNodes;
   I.e. simply return a DOM object and use prose to describe any special
   behavior.

D) attribute sequence<File> files;

E) createIndex(..., sequence<DOMString> key, ...);
   (somewhat simplified as createIndex accepts both a sequence or a single
   value)

F) sequence<ClientRect> getClientRects();
   This would always return a new sequence. Not sure what syntax to use to
   describe returning frozen JS-Arrays.

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

Received on Wednesday, 30 October 2013 18:19:32 UTC