Re: Detecting and Creating Events

On Fri, Aug 28, 2009 at 6:21 AM, Stewart
Brodie<stewart.brodie@antplc.com> wrote:
> 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]
>

Taking things out of context hinders communication.

>> > 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 -


So again, what "DOM code" are you talking about?

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.
>
>

I'm not rooting my inbox to find the example and repost it again.

>
>> > 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.


So what? The simplest path for mapping types would be to follow
ECMA-262 r3's tables for ToNumber, ToString, ToBoolean,(and ToObject,
though I don't know where that one would fit in off the top of my
head).

> 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.
>

Following ToBoolean, yes.

> 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.

And you view this as an obstacle?

You can't figure how to implement something like:- !!obj.canBubbleArg
- or - Boolean(obj.canBubbleArg) - in native code?

 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.
>

Which non-IDL type? Each property can be mapped to a type, internally.

> 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 is not an alternative to the problems that you seemed to misunderstand.

1) The initXXXMethods aren't extensible, are clunky
2) No good way to detect event support

>> 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.
>

No trust required at all. Passing arbitrary values to methods doesn't
always result in a happy ending. Stupidty and reckless, arbitrary
decisions often result in undesirable outcomes. Lived at all?

Regardless, it is still a bit Red Herring. Any value can be converted,
should conversion need to be done, just as with - !!obj.canBubbleArg -
.

>> > 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.
>

Pure fiction. Even if what you wrote were true, and it is not true at
all, but even if it were, it does not preclude the possibility. But it
is not a mere possibility.

ECMAScript can pass an object to the DOM implementation, requiring it
to get properties from that object, or "look inside that object" which
is "an opaque blob" as you've put it. You've gone on now to pure bs
and making up terminology.

One case where ECMAScript program passes an object to a DOM Method is
addEventListener, where the second parameter is specified not to be a
function, but to be an actual EventListener:-

| interface EventTarget {
|   void               addEventListener(in DOMString type,
|                                       in EventListener listener,
|                                       in boolean useCapture);

And we can look to see that an EventListener is an object with a -
handleEvent - method:-

| interface EventListener {
|   void               handleEvent(in Event evt);
| };

- and so to follow this standard, a, plain old js object, with a -
handleEvent - method is passed to - addEventListener -.

And in an example, we can see that the DOM implementation does add the
event listener and does call its - handleEvent - method when the
document is clicked.

Results:-
Opera 10, Firefox 3.5, SeaMonkey/1.1.17, Chrome 2.0.172.39:

PASS [object MouseEvent]

Example:-

<!doctype html>
<html>
<head>
<title>Stuart!</title>
</head>
<body>
<pre id="m">-</pre>
<script type="text/javascript">
document.addEventListener(
  { toString: function(){return"click";}},
  {handleEvent : function(ev){
    document.getElementById("m").firstChild.data = "PASS "+ ev;}},
true);
</script>
</body>
</html>

So, we can see that not only is it possible for an object to be passed
to a DOM Implementation, but we already have a working example of this
in browsers today.

So again, just a red herring.

Garrett

Received on Friday, 28 August 2009 18:18:10 UTC