RE: Thoughts on ES5 binding modifications (was: RE: Java bindings generated from Web IDL)

Continuing this conversation...


> Cameron McCormack:
> > > Note that even a [Replaceable] attribute is handled as an accessor 
> > > property.  Its [[Set]] reconfigures itself to a data property.
>
> Travis Leithead:
> > Excellent. In IE9, the [[set]] just adds an override to the window 
> > instance, "shadowing" the accessor on the prototype.
>
> Actually that is what the spec requires, sorry:
>
>   http://dev.w3.org/2006/webapi/WebIDL/#dfn-attribute-setter

>
> The new property is defined on the instance.

Yes, I think we are in agreement. IE9 is currently doing what is described in 
the link above for [Replaceable] attributes.

--

> > >> (Do you mean operation overloading?)  It might indeed be possible 
> > >> to remove the crazy language about operator overloading currently 
> > >> in the spec, replacing it perhaps with default values and/or allowing 
> > >> union types to be defined.  Noted an issue in the spec.
>
> (See how I typed “operator overloading” there too? :))
>
> > I would love to see a resolution to this. It's been challenging to 
> > implement the Canvas APIs which have some of the most complicated 
> > overloading I've yet encountered.
>
> You mentioned at one point that you were able to “solve” the overloading 
> problem purely with specifying optional argument default values, is that 
> right?  How did you handle
>
>   ImageData createImageData(in double sw, in double sh);
>   ImageData createImageData(in ImageData imagedata);
>
> ?

Sure, though I don't want to rathole on this--our solution isn't the best either because we don't have a great union-types syntax--the burden of resolving the parameters has to happen by object inspection interior to the API in question. I created an attribute "map" syntax that describes what the union types are to help clarify these situations (msApplicableTypes):
 
ImageData createImageData(
            [msApplicableTypes{float, ImageData}] in any imageDataOrSw, 
            in optional float sh);

Another complicated one is drawImage, which has 6 overloads:

Here's what's in the standard:

void drawImage(in HTMLImageElement image, in float dx, in float dy, optional in float dw, in float dh);
void drawImage(in HTMLImageElement image, in float sx, in float sy, in float sw, in float sh, in float dx, in float dy, in float dw, in float dh);
void drawImage(in HTMLCanvasElement image, in float dx, in float dy, optional in float dw, in float dh);
void drawImage(in HTMLCanvasElement image, in float sx, in float sy, in float sw, in float sh, in float dx, in float dy, in float dw, in float dh);
void drawImage(in HTMLVideoElement image, in float dx, in float dy, optional in float dw, in float dh);
void drawImage(in HTMLVideoElement image, in float sx, in float sy, in float sw, in float sh, in float dx, in float dy, in float dw, in float dh);

and here's how we have it described:

void drawImage(
    [msApplicableTypes{HTMLImageElement, HTMLCanvasElement, HTMLVideoElement}] in HTMLElement image,
    in float offsetX,
    in float offsetY,
    in optional float width, 
    in optional float height,
    in optional float canvasOffsetX,
    in optional float canvasOffsetY,
    in optional float canvasImageWidth,
    in optional float canvasImageHeight);

Depending on the number of optional parameters received we [internal to the API] pick from among the allowed representations, ensuring that an even number of parameters are received, and validating the types.

Again, I don't want this to appear that I'm pushing to have WebIDL adopt this particular syntax--rather I'm just saying that there are other options to consider than using operation overloading.

--

> Travis Leithead:
> > > > * The ability to specify an “interface object only” interface
> > > >   (e.g., NodeFilter, needed for the W3C DOM L2 Traversal spec)
>
> Cameron McCormack:
> > > Is that one that is only ever implemented by native objects?  The 
> > > spec currently allows native objects to be passed in for such interfaces, 
> > > but there’s no annotation to note that host objects will never implement it.
> > > What benefit would that have?
>
> Travis Leithead:
> > Yes, currently our IE9 NodeFilter is wholly a native object, just 
> > present to provide the constants; it's not the same thing we allow in 
> > the createNodeIterator method, which must be a Function.
> 
> OK, but I am not sure what specifying “interface object only” actually 
> means, then. What would it change in the ES binding?  (The lack of a 
> prototype object?)

Yes, exactly. In IE9 specifically, any "msInterfaceObjectOnly" annotated interface will not have a prototype property (or corresponding interface prototype object), nor will support any operations or attributes found on the interface (it ignores them). There are only three occurances of this annotation in IE9:
* NodeFilter (ignores "acceptNode()" operation)
* SVGUnitTypes
* SVGZoomAndPan (ignores "zoomAndPan" property)

SVGRenderingIntent was also annotated this way, but is not supported in IE9

--

> > > > [global polluter extended attribute]
> > >
> > > Is this for things like <span id=abc> causing a global, replaceable 
> > > variable named "abc" to be available?
> > 
> > No, not the same thing. Our global object polluter attribute (module
> > level) just tells which interface to hookup as the JavaScript global 
> > object's prototype :)
>
> Specifying what object is returned by Object.getPrototypeOf(window)?
> Can you demonstrate how such an extended attribute would be used?

Let me clarify that in no way am I encouraging you to adopt this attribute for WebIDL. In IE9 it is purely an informative attribute meant to describe the variation from ES5 when a scripting engine is hosted in a browser.

In ES5, the global object's prototype is Object.prototype. E.g., (from global scope) Object.prototype === Object.getPrototypeOf(this).

This is true when IE9's script engine is run independently of a browser (say as an OS scripting engine like cscript). However, when the script engine is hosted in the browser, we "pollute" the global object with the DOM :) This is accomplished by inserting a prototype object between "this" (global instance) and Object.prototype. The [msGlobalObjectPollutor=Window] attribute indicates that the Window interface prototype object should be inserted as the "polluter". Thus, when the script engine is hosted in the browser, the preceding assertion in ES5 is no longer true. Rather:

Window.prototype === Object.getPrototypeOf(this)
Object.prototype === Object.getPrototypeOf(Object.getPrototypeOf(this))

--

-Travis

Received on Wednesday, 3 November 2010 18:49:20 UTC