Re: Detecting and Creating Events

Garrett Smith <dhtmlkitchen@gmail.com> wrote:

> On Mon, Aug 24, 2009 at 2:54 AM, Stewart
> Brodie<stewart.brodie@antplc.com> wrote:
> > Garrett Smith <dhtmlkitchen@gmail.com> wrote:
> >
> >> On Thu, Aug 20, 2009 at 4:32 AM, Stewart
> >> Brodie<stewart.brodie@antplc.com> wrote:

> > > > I don't like Object being passed to a DOM method. The moment you
> > > > permit arbitrary JS objects in a DOM API, the implementation of that
> > > > method has to deal with so many more problems (e.g. dealing with
> > > > infinities, NaNs, other objects).
> >> >
> >>
> > > Infinity and NaN are numbers, not objects.
> >

[I've joined two of my and two of your comments here for simplicity]

> > I wasn't clear.  These arbitrary objects that you are intending to pass
> > in to this method may have any number of properties, the types of these
> > properties may be infinities, NaNs, numbers, other objects, strings,
> > etc.   Thus DOM code now has to be able to deal with these types,
> 
> What "DOM code"? Again, inifinity, NaN, and number are all "number" type;
> they don't fall in the category of "object" or "other objects".

DOM is language neutral - you can bind it to multiple languages, not just
ECMAScript.  Consequently, DOM is defined in terms of a set of language
neutral types.  This set of types excludes infinities and NaNs.
(http://dev.w3.org/2006/webapi/WebIDL/#idl-types)

Therefore, DOM implementations do not need to ever deal with types not in
the set of common types.  So take this example:

  dispatchInitedEvent( "foo", { someprop: -Infinity } )

That code would be fine IF dispatchInitedEvent doesn't look inside the
object to find someprop.  However, as far as I can tell in your scheme, it
does (because it has to look for those properties), given that you are
requiring the DOM implementation to extract each property from the object
and insert it into the newly created event object.



> > it does not because, to use my examples, infinities and NaNs are not
> > permitted in a DOM interface.
> 
> So? If I pass - 0 - to - initMouseEvent - as the - canBubbleArg - ,
> isn't the program in the same position?

No.  The calling language is required to marshal the function parameters
into a DOM compatible type using type information for the called method.  In
fact, you could pass Infinity as the canBubbleArg from ECMAScript if you
wanted.  The difference is that the calling language is what is interpreting
the value and converting it (to a boolean - so infinities would be 'true'
and NaNs would be 'false') not the DOM implementation.

The issue regarding which code is interpreting values and performing type
conversions is fundamentally important.  Only the ECMAScript implementation
can interpret values of native ECMAScript types.  Only the ECMAScript
implementation can perform the type coercion, although it does so at the
request of the DOM implementation.



> A)
> var bubbles = 0; // Programmer error: should be boolean.
> obj.initMouseEvent("click", bubbles , false [,etc...]);
> 
> B)
> var bubbles = 0; // Programmer error: should be boolean.
> obj.dispatchInitedEvent("MouseEvent", "click", {
>   canBubbleArg : bubbles ,
> });
> 
> Same problem.  Doesn't matter how the value is passed.

No, it's a completely different problem.  In the first version, the type
coercion occurs in the ECMAScript implementation (at the behest of the DOM
implementation, based on the type information for initMouseEvent), whereas
in the second version, you would need the DOM implementation to understand
how to convert an ECMAScript native type into a DOM type.  This matters a
lot.  Let me requote your example but with a minor change to the value:

A)
var bubbles = NaN; // Programmer error: should be boolean.
obj.initMouseEvent("click", bubbles , false [,etc...]);

B)
var bubbles = NaN; // Programmer error: should be boolean.
obj.dispatchInitedEvent("MouseEvent", "click", {
  canBubbleArg : bubbles });

Example A will work fine because the ECMAScript implementation will convert
the NaN to false.  The reason why this works is that the method
implementation for initMouseEvent() will state that the parameter concerned
is expected to be of type boolean, so the *calling language* implementation
(the ECMAScript implementation) is requested to convert the value to
boolean. The ECMAScript implementation uses its ToBoolean operation for this
(and ends up with a boolean (false) as per the ECMAScript specification) and
this is the value that the DOM method implementation actually sees.

Example B would not work because the DOM method implementation for
dispatchInitedEvent will be faced with the task of extracting individual
properties from this arbitrary object in order to then put them into the
newly created Event object.  Therefore, the DOM method implementation would
end up needing to handle this non-IDL type.

An alternative approach would to just use a CustomEvent for everything and
pass your arbitrary object in as the detailArg.  Your listeners would then
have to extract properties from the object, rather than having them as
members of the Event object itself, though.  However, the DOM implementation
never looks inside detailArg - it simply passes it back to the original
implementation that created it in the first place.


> That "problem" exists either way, so cannot be considered a valid reason
> for not using an object of properties and favoring an ArgumentList.  More
> like a red herring.


> 
> An implementation might handle that invalid value by throwing an error, or
> it might want to use ECMAs ToBoolean. Or the program could just not do
> that.

No; totally impossible; trusting the content author not to do it is not
acceptable.

> > In all the other cases I've noticed where arbitrary objects are passed
> > to a DOM method, the object is only ever passed back to the scripting
> > engine that created it and interpreted there.
> 
> I'm not seeing the point.

DOM has an object type.  Thus an ECMAScript implementation can create an
ECMAScript object (and put whatever properties it likes in it, including
properties with values that are not part of the set of standard DOM types).

ECMAScript can pass this ECMAScript object to a DOM implementation as an
opaque blob, and the DOM implementation can pass it back to the ECMAScript
implementation (e.g. CustomEvent::detailArg), but it CANNOT require the DOM
implementation to look inside that object - it's opaque to the DOM
implementation.


-- 
Stewart Brodie
Software Engineer
ANT Software Limited

Received on Friday, 28 August 2009 13:21:56 UTC