RE: Faking host objects

You should not try to replicate Chrome too much. My personnal experience told me that Chrome do not respect WebIDL in many occasions. For example, the DOMInterface.prototype should be of type “DOMInterfacePrototype” and this is not the case in Chrome; also, most properties that should be ‘getter/setter’ following WebIDL are considered value properties in Chrome, something that’s not logical (a value property does not have a setter so should no throw an error when set, nor perform type conversions). 

 

Internet Explorer does a much better job than the other browsers on that matter because they rewrote their binding API entirely for IE9 and followed the WebIDL spec very closely. Here are some examples:
 
({}).toString.call(Node.prototype);
"[object NodePrototype]"

 

Object.getOwnPropertyDescriptor(HTMLElement.prototype, "onclick");
{
    get : function onclick() { [native code] } ,
    set : function onclick() { [native code] } ,
    enumerable : true,
    configurable : true
}
 
BTW, Object.getOwnPropertyDescriptor(Event.prototype,'initEvent').enumerable returns “true” on my computer, so I don’t see exactly why you set enumerable to false. By the way, the WebIDL spec clearly states that properties have [[Enumerable]] set to true if not specified otherwhise: http://dev.w3.org/2006/webapi/WebIDL/#ecmascript-binding

 
François

 

 

De : Marcos Caceres
Envoyé : ‎29‎ ‎décembre‎ ‎2012 ‎18‎:‎21
À : François REMY
Cc : public-nextweb@w3.org
Objet : Re: Faking host objects



On Saturday, 29 December 2012 at 16:04, François REMY wrote:
> The problem with your code is that the instances don’t really inherit from the exposed prototype:
>  
> // let fooInstance be an instance of Foo, got somehow from your API
> Foo.prototype.test2=Foo.prototype.test;
> fooInstance.test2(); // fail

The above must fail, because test2 is a copy of test whose "this" has changed.   

It's kinda hard to speak about these in abstract terms. It's probably best to use something like window.Node or window.Event.  

The good thing about window.Node is that a developer can't construct one manually, as opposed to window.Event, which does have a public constructor.  

Currently, in the code I posted, you can't construct instances from the "interface object" (i.e., from something equivalent to window.Event, which would be new Event("")).  

This requires the implementation of the overload resolution algorithm:
http://dev.w3.org/2006/webapi/WebIDL/#es-interface-call


I need to implement that this coming week, as MIDIEvent will need to expose a public constructor.  
>  
> I’m pretty sure there’s a good reason, but why don’t you use the straigforward approach (aka: window.publicFoo = function() { ... }; window.Foo.prototype := privateFoo.prototype) ?
>  
>  
>  
>  

That's basically what the code does at the moment, but enumeration needs to be disabled. Also, the reason you can't do the above:

window.publicFoo = function() { ... };

is that you need to prevent new instances of publicFoo from being created. Also, in Chrome, publicFoo() will have the Empty object as its prototype. That's not a big deal, but it should be Object.

Remember, the aim of the game here is to replicate as exactly as possible what the browser does (I'm using Chrome as the canonical implementation, for better or for worst).

Received on Saturday, 29 December 2012 18:12:31 UTC