- From: Cameron McCormack <cam@mcc.id.au>
- Date: Tue, 14 Jun 2011 12:15:49 +1200
- To: public-script-coord@w3.org
- Cc: ian@hixie.ch
One of the last major outstanding bugs in Web IDL is to get rid of multiple inheritance and the mixin prototype object. When I, TC39 folks and others discussed this late last year, we came up with this proposal: * interfaces come in two types: regular interfaces and mixin interfaces (Jonas argued for calling these “classes” and “interfaces” instead, IIRC) * regular interfaces can inherit only from a single other regular interface * all regular interfaces get interface objects (unless [NoInterfaceObject] is specified on them), and mixin interfaces never get interface objects * in an “implements” statement, the interface on the RHS must be a mixin interface * if there is an “A implements B” statement, then all properties for operations/attributes/constants/etc. for B go on A’s interface prototype object In starting to implement this change, I’ve realised that there is a case it doesn’t handle, which is when you have a mixin interface that not all objects of a certain type implement. For example, in the HTML5 spec there are statements like this: http://whatwg.org/html/#loading-xml-documents A Document object that is an XML document that was created by the DOMImplementation.createDocument() factory method must also implement the XMLDocumentLoader interface http://whatwg.org/html/#dom-showmodaldialog The Window objects of Documents hosted by browsing contexts created by the above [showModalDialog] algorithm must also implement the WindowModal interface. So, not all Document objects implement XMLDocumentLoader, and not all Window objects implement WindowModal. How should we handle these? Should we keep the concept of a mixin interface object to handle these cases? If we don’t want to, we could change the HTML spec to define XMLDocumentLoader as interface XMLDocumentLoader : Document { ... }; and say that the object returned from DOMImplementation.createXMLDocument is an XMLDocumentLoader object. (Renaming XMLDocumentLoader to XMLDocument probably makes sense in that case.) The WindowModal one is an interesting case, because for each distinct Window (global) object there is a whole set of interface objects, prototypes, etc. So it would actually be safe to put the WindowModal properties on Window.prototype directly. If you could restrict it just to the environment created by showModalDialog, you could Window implements WindowModal; but as it stands the statement above would apply to all sets of “initial objects”. http://dev.w3.org/2006/webapi/WebIDL/#es-environment Another problem, which I am not sure exists just yet, is what to do if you want to use an interface both as a concrete thing to inherit from and as a mixin. Let’s take EventTarget as the example and assume we want to follow the recent changes to DOM Core to make it the super- interface of Node: interface EventTarget { ... }; interface Node : EventTarget { ... }; interface XMLHttpRequest : EventTarget { ... }; That works fine, and we can now monkeypatch EventTarget.prototype and affect Node and XHR objects. But what if we have an existing interface hierarchy where we want to make a non-root interface implement EventTarget: interface AbstractThingamy { ... }; interface InteractiveThingamy : AbstractThingamy { ... }; InteractiveThingamy implements EventTarget; That would be disallowed in this proposal, since the RHS of the implements statement is a regular interface. One of the advantages of the proposal was that by never having an interface prototype object for mixins, you avoid authors mistakenly thinking that modifying that object will affect all objects that implement that interface. If we allow the above, then we have a distinct prototype object for EventTarget, and changes to it will affect Node and XHR objects but will have no affect on InteractiveThingamy objects. Another advantage was that by not having an interface object, we don’t have to worry about having custom [[HasInstance]] behaviour and we can always just rely on the native “look up the prototype chain” semantics. I think the strongest reason for reforming interface inheritance in Web IDL is to ensure that mixed-in interface properties get placed on the right objects. So that, for example, the WindowTimers properties setTimeout etc. get put on Window.protoype, because `Window implements WindowTimers`. I would be fine with not making the distinction between regular and mixin prototypes, bearing the cost of possible author confusion when modifications to EventTarget.prototype (in the example above) don’t affect InteractiveThingamy, and keeping [NoInterfaceObject] annotations on interfaces that really are mixins and which are unlikely to appear as the ancestore of another interface. I think that is the simplest change to make, but I am interested to hear others’ opinions. -- Cameron McCormack ≝ http://mcc.id.au/
Received on Tuesday, 14 June 2011 00:16:31 UTC