- From: Boris Zbarsky <bzbarsky@mit.edu>
- Date: Tue, 24 Mar 2015 16:55:51 -0400
- To: www-style@w3.org
- CC: "public-script-coord@w3.org" <public-script-coord@w3.org>
On 3/24/15 4:35 PM, Simon Pieters wrote: > [Constructor(optional DOMPointInit p1, optional DOMPointInit p2, > optional DOMPointInit p3, optional DOMPointInit p4), > Constructor(optional DOMRectInit rect), .... > * All arguments are optional. This is invalid WebIDL since it's not > possible to distinguish which constructor to use. For other constructors > I've let the dictionary be optional and have the other constructor have > two required arguments. We can do that here as well. This is exciting. DOMRectInit and DOMPointInit are both dictionaries, right? WebIDL has this bit: If the type of an argument is a dictionary type or a union type that has a dictionary type as one of its flattened member types, and this argument is either the final argument or is followed only by optional arguments, then the argument MUST be specified as optional. which means that at the moment the constructor version that takes 4 DOMPointInit arguments must in fact have them all be optional. So you can't do what you propose as things stand. While that requirement about having trailing dictionary arguments be optional makes sense for dictionaries used as options objects (where lack of the options object really had better be equivalent to passing {} in terms of API design), it doesn't really make much sense here, because these arguments aren't really options objects. In fact, if I saw someone doing this: new DOMQuad({}, {}, {}, {}); I would be pretty confused... One plausible approach here would be to make the Web IDL spec change proposed in https://www.w3.org/Bugs/Public/show_bug.cgi?id=27953 and then make the members of DOMPointInit required and the DOMPointInit arguments non-optional. But it's also worth running this whole idea by someone familiar with JS API design. The overload setup being proposed is basically relying on arguments.length to disambiguate which constructor was meant. How would JS code normally handle this situation? Possibly via arguments.length, but possibly via testing the first argument to see whether it has a .width property or whatever... > * If one does `new DOMQuad(other_domquad)`, it will convert the object > to a DOMRectInit and result in the same thing as `new DOMQuad({})` which > is probably not what was intended. Supporting two kinds of dictionaries > is not straightforward, though, since I think WebIDL doesn't distinguish > between different dictionaries. Right, because they're all just objects and there's no really principled way to do it. You could distinguish in prose, of course, at the expense of having to decide _how_ to distinguish and writing the prose. Either via your proposal of having a dictionary that's the union of the two dictionaries, or by making the argument be "object" and doing the conversions to dictionary by hand. Of course if you're doing that, you could just write it as: Constructor(optional DOMPointOrRectOrQuadInit arg1, optional DOMPointInit p2, optional DOMPointInit p3, optional DOMPointInit p4) and then the prose would see which members of arg1 are present and if so decide whether to throw or look at p2-p4 or what. -Boris
Received on Tuesday, 24 March 2015 20:56:21 UTC