Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Javascript > Detecting support for event types

Reply
Thread Tools

Detecting support for event types

 
 
RobG
Guest
Posts: n/a
 
      08-15-2008
When using createEvent, an eventType parameter must be provided as an
argument. This can be one of those specified in DOM 2 or 3 Events, or
it might be a proprietary eventType[1].

My problem is testing for support of particular eventTypes - the DOM 2
Events Interface DocumentEvent says that if the eventType is not
supported, it throws a DOM exception[2]. This makes testing rather
tough - if you try something like:

if (document && document.createEvent &&
document.createEvent(eventType)) {...}

or a typeof test and the eventType (say 'MouseEvents') isn't
supported, the script crashes with a DOM execption as specified in the
DOM 2 Events spec. I can do try..catch but I'd rather not if I can
avoid it:

var eventType = 'MouseEvents';
try {
document.createEvent(eventType);
alert(eventType + ' OK');
} catch (e) {
alert(eventType + ' not supported by createEvent');
return;
}


Is there a feature test that can be used?


1. Gecko supporte eventTypes:
<URL: http://developer.mozilla.org/en/docs...nt.createEvent
>


2. W3C DOM 2 Events: Interface DocumentEvent - createEvent
<URL: http://www.w3.org/TR/DOM-Level-2-Eve...nt-createEvent
>



--
Rob
 
Reply With Quote
 
 
 
 
RobG
Guest
Posts: n/a
 
      08-15-2008
On Aug 15, 2:04*pm, RobG <(E-Mail Removed)> wrote:
> When using createEvent, an eventType parameter must be provided as an
> argument.


While I'm at it, is there a list somewhere of the events that belong
to each event type (e.g. click, mouseup and mousedown belong to
MouseEvents while focus and blur belong to UIEvents), or do I have to
guess them and test by trial and error?


--
Rob
 
Reply With Quote
 
 
 
 
Martin Honnen
Guest
Posts: n/a
 
      08-15-2008
RobG wrote:

> While I'm at it, is there a list somewhere of the events that belong
> to each event type (e.g. click, mouseup and mousedown belong to
> MouseEvents while focus and blur belong to UIEvents), or do I have to
> guess them and test by trial and error?


The W3C DOM Level 2 Events specification lists events, for instance see
http://www.w3.org/TR/DOM-Level-2-Eve...Events-UIEvent
then you will find DOMFocusIn, DOMFocusOut, and DOMActivate.

--

Martin Honnen
http://JavaScript.FAQTs.com/
 
Reply With Quote
 
Peter Michaux
Guest
Posts: n/a
 
      08-18-2008
On Aug 14, 9:04*pm, RobG <(E-Mail Removed)> wrote:
> When using createEvent, an eventType parameter must be provided as an
> argument. *This can be one of those specified in DOM 2 or 3 Events, or
> it might be a proprietary eventType[1].
>
> My problem is testing for support of particular eventTypes - the DOM 2
> Events Interface DocumentEvent says that if the eventType is not
> supported, it throws a DOM exception[2]. *This makes testing rather
> tough - if you try something like:
>
> * if (document && document.createEvent &&
> document.createEvent(eventType)) {...}
>
> or a typeof test and the eventType (say 'MouseEvents') isn't
> supported, the script crashes with a DOM execption as specified in the
> DOM 2 Events spec. *I can do try..catch but I'd rather not if I can
> avoid it:
>
> * var eventType = 'MouseEvents';
> * try {
> * * document.createEvent(eventType);
> * * alert(eventType + ' OK');
> * } catch (e) {
> * * alert(eventType + ' not supported by createEvent');
> * * return;
> * }
>
> Is there a feature test that can be used?


Second paragraph here

<URL: http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-eventgroupings-mouseevents>

indicates something like the following would be sufficient

if (typeof document == 'object' && document &&
document.implementation &&
document.implementation.hasFeature &&
document.implementation.hasFeature('MouseEvents', 2.0))

But the browser may well still be lying as this implies the
MouseEvents interface is present *and* works. Evidence has shown that
many features are present in browsers but don't work. This may be too
paranoid.

See also Flanagan's 5th edition page 314 for a list of module names
that can be used for hasFeature, page 404 in the events section, and
page 776 in the reference section. (Flanagan's 4th edition has the
same content indexed.)

Peter
 
Reply With Quote
 
RobG
Guest
Posts: n/a
 
      08-18-2008
On Aug 18, 10:14 am, Peter Michaux <(E-Mail Removed)> wrote:
> On Aug 14, 9:04 pm, RobG <(E-Mail Removed)> wrote:
>
>
>
> > When using createEvent, an eventType parameter must be provided as an
> > argument. This can be one of those specified in DOM 2 or 3 Events, or
> > it might be a proprietary eventType[1].

>
> > My problem is testing for support of particular eventTypes - the DOM 2
> > Events Interface DocumentEvent says that if the eventType is not
> > supported, it throws a DOM exception[2]. This makes testing rather
> > tough - if you try something like:

>
> > if (document && document.createEvent &&
> > document.createEvent(eventType)) {...}

>
> > or a typeof test and the eventType (say 'MouseEvents') isn't
> > supported, the script crashes with a DOM execption as specified in the
> > DOM 2 Events spec. I can do try..catch but I'd rather not if I can
> > avoid it:

>
> > var eventType = 'MouseEvents';
> > try {
> > document.createEvent(eventType);
> > alert(eventType + ' OK');
> > } catch (e) {
> > alert(eventType + ' not supported by createEvent');
> > return;
> > }

>
> > Is there a feature test that can be used?

>
> Second paragraph here
>
> <URL:http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-eventgroup...>
>
> indicates something like the following would be sufficient
>
> if (typeof document == 'object' && document &&
> document.implementation &&
> document.implementation.hasFeature &&
> document.implementation.hasFeature('MouseEvents', 2.0))


Looks familiar...


> But the browser may well still be lying as this implies the
> MouseEvents interface is present *and* works. Evidence has shown that
> many features are present in browsers but don't work. This may be too
> paranoid.


I don't think it's paranoid, just common sense. The W3C hasFeature is
no better than feature inference, it doesn't actually test for
support. It would have been much better (though still not sufficient)
if they'd specified hasFeature return null for unsupported eventTypes,
like getElementById does if there's no element with the specified id.


> See also Flanagan's 5th edition page 314 for a list of module names
> that can be used for hasFeature, page 404 in the events section, and
> page 776 in the reference section. (Flanagan's 4th edition has the
> same content indexed.)


Yeah, looked there. Following Martin's advice I created my own list
from various sources, here's what I have so far:

var allFeatures = {

Safari : ['TouchEvent', 'GestureEvent'],

Gecko : ['MessageEvent', 'MouseScrollEvents', 'PopupEvents',
'PopupBlockedEvents', 'XULCommandEvent',
'XULCommandEvents'],

SVG : ['SVGEvents', 'SVGEvent', 'SVGZoomEvents',
'SVGZoomEvent'],

DOM2 : ['UIEvents', 'MouseEvents', 'MutationEvents',
'HTMLEvents'],

DOM3 : ['UIEvent', 'MouseEvent', 'MutationEvent',
'MutationNameEvent', 'TextEvent', 'TextEvents',
'KeyboardEvent', 'KeyEvents', 'Event', 'Events']
};


and the supported events for each interface (wrapped for posting, not
all features added yet):

var ifaces = {
UIEvents : 'DOMFocusIn DOMFocusOut DOMActivate',

MouseEvents : 'click mousedown mouseup mouseover mousemove'
+ ' mouseout',

MutationEvent : 'DOMSubtreeModified DOMNodeInserted'
+ ' DOMNodeRemoved DOMNodeRemovedFromDocument'
+ ' DOMNodeInsertedIntoDocument DOMAttrModified'
+ ' DOMCharacterDataModified',

HTMLEvents : 'load unload abort error select change'
+ ' submit reset focus blur resize scroll',

// Draft events
TouchEvent : 'touchstart touchmove touchend touchcancel',

GestureEvent : 'gesturestart gesturechange gestureend'
};


I'm still working on the best way to organise them, I need to study
the W3C specs more. Perhaps I need to use hasFeature first, then
try..catch. The idea is to have a pre-calculated list of supported
event interfaces and types, then allow calling them by:

sendEvent( elementId, eventType [, parameterObject])

where each event type has a default parameter object that can be
modified by passing an object with just the parameters that need to be
set to some other value.

The event interface to use with createEvent is calculated from the
list of supported interfaces. If the appropriate interface isn't
supported, the event isn't dispatched.

All this started because I wanted to know a good way of detecting
support for touch events and expanded to be a more general way to send
any event into the DOM.

It seems Mozilla has changed its position on dispatchEvent. I'm
pretty sure that in Firefox 2 when a click event was fired on a link
using dispatchEvent, it follow the link, but Firefox 3 doesn't (nor
does IE using fireEvent), Safari 3 does. I haven't got to testing
other browsers but I expect this will only work in fairly modern
versions.

Maybe I'll go back to my original plan and do this just for touch
events.


--
Rob
 
Reply With Quote
 
Peter Michaux
Guest
Posts: n/a
 
      08-18-2008
On Aug 17, 6:13 pm, RobG <(E-Mail Removed)> wrote:

[snip]

> I'm still working on the best way to organise them, I need to study
> the W3C specs more. Perhaps I need to use hasFeature first, then
> try..catch.


What does that gain over just using try-catch? The only issue with try-
catch is it may syntax error in old browsers.

> The idea is to have a pre-calculated list of supported
> event interfaces and types, then allow calling them by:
>
> sendEvent( elementId, eventType [, parameterObject])
>
> where each event type has a default parameter object that can be
> modified by passing an object with just the parameters that need to be
> set to some other value.


This reads like prototype-based inheritance and I find it is rare to
actually find situations where prototype-based inheritance is so
appropriate.

> The event interface to use with createEvent is calculated from the
> list of supported interfaces. If the appropriate interface isn't
> supported, the event isn't dispatched.


The way my feature testing has evolved would mean this "failure" is
too late. If the DOM has been manipulated and then depends on this
dispatch being successful and the dispatch will fail then the DOM
never should have been manipulated in the first place. In other words,
a widget isn't initialized unless it can be fully functional.


> All this started because I wanted to know a good way of detecting
> support for touch events


Apple's documentation is disappointingly dependent on
navigator.userAgent parsing.

> and expanded to be a more general way to send
> any event into the DOM.


I've never had any need for production code to send and even to a DOM
element. Do you?

Sending events to DOM elements could be useful in a test library.
Selenium does this but the code specific to each browser is a little
scary (admittedly they are writing something difficult.)

> It seems Mozilla has changed its position on dispatchEvent. I'm
> pretty sure that in Firefox 2 when a click event was fired on a link
> using dispatchEvent, it follow the link, but Firefox 3 doesn't (nor
> does IE using fireEvent), Safari 3 does. I haven't got to testing
> other browsers but I expect this will only work in fairly modern
> versions.
>
> Maybe I'll go back to my original plan and do this just for touch
> events.


What does something like
document.implementation.hasFeature('TouchEvent', 1.0) return?

Peter
 
Reply With Quote
 
Thomas 'PointedEars' Lahn
Guest
Posts: n/a
 
      08-18-2008
RobG wrote:
> When using createEvent, an eventType parameter must be provided as an
> argument. This can be one of those specified in DOM 2 or 3 Events, or
> it might be a proprietary eventType[1].
>
> My problem is testing for support of particular eventTypes - the DOM 2
> Events Interface DocumentEvent says that if the eventType is not
> supported, it throws a DOM exception[2]. This makes testing rather
> tough - if you try something like:
>
> if (document && document.createEvent &&
> document.createEvent(eventType)) {...}
>
> or a typeof test and the eventType (say 'MouseEvents') isn't
> supported, the script crashes with a DOM execption as specified in the
> DOM 2 Events spec.


It does _not_ really *crash* with the exception; the method *throws* the
(runtime) exception and you missed catching it.

> I can do try..catch but I'd rather not if I can avoid it:


You cannot avoid it, this is exactly what the exception and consequently the
TryStatement with a Catch part is for. It has been learned from e.g. Java
that exceptions allow subroutines to return to their caller with a failure
state immediately, and exception handling allows the caller to recognize and
handle that state, without having to define a return value for each kind of
failure which would then no longer be available as return value for proper
execution.

> var eventType = 'MouseEvents';
> try {


You should add the "supposedly callable" feature test here, see below.

> document.createEvent(eventType);
>
> alert(eventType + ' OK');
> } catch (e) {
> alert(eventType + ' not supported by createEvent');
> return;
> }
>
> Is there a feature test that can be used?


try...catch can be eval()'d to hide it from incompatible parsers:

/**
* Wrapper for safer <code>try</code>...<code>catch</code>.
*
* Attempts to evaluate a value as a <i>StatementList</i>, and attempts
* to evaluate another value as a <i>StatementList</i> if an exception
* is thrown in the process. The argument identifiers may be used
* in each value to refer to the used values; the <code>code</code>
* word may be used to the refer to the entire constructed
* <code>try</code>...<code>catch</code> string that is evaluated
* as a <i>Program</i>.
*
* @param statements
* Value to be evaluated as a <i>StatementList</i>.
* Called if a <code>Function</code> object reference, converted
* to string if not a string, and used as-is otherwise.
* For compatibility, the <code>undefined</code> value
* is evaluated like the empty string.
* @param errorHandlers
* Value to be evaluated as a <i>StatementList</i> in case of an
* exception. Called if a <code>Function</code> object reference,
* converted to string if not a string, and used as-is otherwise.
* For compatibility, the <code>undefined</code> value
* is evaluated like the empty string.
* @return
* The result of <code>statements</code>, or the result
* of <code>errorHandlers</code> if an error occurred.
* @author
* Copyright (c) 2008
* Thomas 'PointedEars' Lahn &lt;(E-Mail Removed)&gt;
* Distributed under the GNU GPL v3 and later.
* @partof JSX:exception.js
*/
function tryThis(statements, errorHandlers)
{
/**
* @param s Value to be stringified
* @return Stringified version of <code>s</code>
*/
function stringify(s)
{
if (typeof s == "function")
{
s = "(" + s + ")()";
}
else if (typeof s == "undefined")
{
s = "";
}

return s;
}

statements = stringify(statements);
errorHandlers = stringify(errorHandlers);

var code = 'try { ' + statements + ' }'
+ 'catch (e) { ' + errorHandlers + ' }';

return eval(code);
}

var eventType = 'MouseEvents';
tryThis(
function() {
if (isMethod(document, "createEvent"))
{
document.createEvent(eventType);
window.alert(eventType + ' OK');
}
},
function() {
window.alert(eventType + ' not supported by createEvent');
});


HTH

PointedEars
--
Prototype.js was written by people who don't know javascript for people
who don't know javascript. People who don't know javascript are not
the best source of advice on designing systems that use javascript.
-- Richard Cornford, cljs, <f806at$ail$1$(E-Mail Removed)>
 
Reply With Quote
 
RobG
Guest
Posts: n/a
 
      08-18-2008
On Aug 18, 12:09 pm, Peter Michaux <(E-Mail Removed)> wrote:
> On Aug 17, 6:13 pm, RobG <(E-Mail Removed)> wrote:
>
> [snip]
>
> > I'm still working on the best way to organise them, I need to study
> > the W3C specs more. Perhaps I need to use hasFeature first, then
> > try..catch.

>
> What does that gain over just using try-catch?


If it returns false, don't even bother with the W3C event model.

I'm still not clear about the difference between the event model and
the Events *module* - does hasFeature('Events', '2.0') just mean
support for interface Event, or does it mean all of the interfaces for
the event model (Event, DocumentEvent, EventListener, EventTarget) but
not the extra ones like UIEvents, MutationEvents, etc.?

Anyhow, I figured hasFeaure might circumvent using try..catch on
interfaces where the module itself isn't supported, e.g. there are 7
interfaces in MutationEvent, if hasFeature(‘MutationEvents’,’2.0’)
returns false, that's 7 try..catch calls that can be avoided. I
figure it's more likely browsers will pretend to support modules than
not, or only implement part of them. Testing will reveal.


> The only issue with try-
> catch is it may syntax error in old browsers.


Yes, Thomas has posted a solution that I'll file away if it's really
needed.


> > The idea is to have a pre-calculated list of supported
> > event interfaces and types, then allow calling them by:

>
> > sendEvent( elementId, eventType [, parameterObject])

>
> > where each event type has a default parameter object that can be
> > modified by passing an object with just the parameters that need to be
> > set to some other value.

>
> This reads like prototype-based inheritance and I find it is rare to
> actually find situations where prototype-based inheritance is so
> appropriate.


No, I have an isSupported method so you'd call:

if (isSupported('UIEvents')) {


The pre-calculated list is kept in isSupported using a closure and is
used so that the feature test doesn't have to happen every time.


> > The event interface to use with createEvent is calculated from the
> > list of supported interfaces. If the appropriate interface isn't
> > supported, the event isn't dispatched.

>
> The way my feature testing has evolved would mean this "failure" is
> too late. If the DOM has been manipulated and then depends on this
> dispatch being successful and the dispatch will fail then the DOM
> never should have been manipulated in the first place. In other words,
> a widget isn't initialized unless it can be fully functional.


It can use the same isSupported test.


> > All this started because I wanted to know a good way of detecting
> > support for touch events

>
> Apple's documentation is disappointingly dependent on
> navigator.userAgent parsing.
>
> > and expanded to be a more general way to send
> > any event into the DOM.

>
> I've never had any need for production code to send and even to a DOM
> element. Do you?


No, but although that isn't where I started it seems to be where I'm
headed. The goal is a feature test for touch events. One approach is
to attach an ontouchstart (or some other touch event) listener and
fire it using dispatchEvent it to see what happens - it seems very
crude but was a starting point. Along the way it occurred to me that
detecting support for the TouchEvent interface might be sufficient and
a little more elegant. Then I got a bit sidetracked into a more
general detection of event modules...


> Sending events to DOM elements could be useful in a test library.
> Selenium does this but the code specific to each browser is a little
> scary (admittedly they are writing something difficult.)


I think I prefer the 'unobtrusive' approach - if it doesn't look like
it'll work, don't attempt it and fallback to simpler stuff.


> > It seems Mozilla has changed its position on dispatchEvent. I'm
> > pretty sure that in Firefox 2 when a click event was fired on a link
> > using dispatchEvent, it follow the link, but Firefox 3 doesn't (nor
> > does IE using fireEvent), Safari 3 does. I haven't got to testing
> > other browsers but I expect this will only work in fairly modern
> > versions.

>
> > Maybe I'll go back to my original plan and do this just for touch
> > events.

>
> What does something like
> document.implementation.hasFeature('TouchEvent', 1.0) return?


I don't know, Apple's documentation doesn't provide any hints on the
version number or whether it should work with hasFeature - '1.0' is as
good a guess as any, I'll try it later.


--
Rob
 
Reply With Quote
 
RobG
Guest
Posts: n/a
 
      08-18-2008
On Aug 18, 4:45*pm, RobG <(E-Mail Removed)> wrote:
> On Aug 18, 12:09 pm, Peter Michaux <(E-Mail Removed)> wrote:

[...]
> > What does something like
> > document.implementation.hasFeature('TouchEvent', 1.0) return?

>
> I don't know, Apple's documentation doesn't provide any hints on the
> version number or whether it should work with hasFeature - '1.0' is as
> good a guess as any, I'll try it later. *


I tried all version numbers from '0.0' to '3.9', all returned false.


--
Rob
 
Reply With Quote
 
RobG
Guest
Posts: n/a
 
      08-18-2008
On Aug 18, 9:26*pm, RobG <(E-Mail Removed)> wrote:
> On Aug 18, 4:45*pm, RobG <(E-Mail Removed)> wrote:
>
> > On Aug 18, 12:09 pm, Peter Michaux <(E-Mail Removed)> wrote:

> [...]
> > > What does something like
> > > document.implementation.hasFeature('TouchEvent', 1.0) return?

>
> > I don't know, Apple's documentation doesn't provide any hints on the
> > version number or whether it should work with hasFeature - '1.0' is as
> > good a guess as any, I'll try it later. *

>
> I tried all version numbers from '0.0' to '3.9', all returned false.


Here's my final effort:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>TouchEvent feature test</title>
<script type="text/javascript">

/* Feature tests for TouchEvent and GestureEvent modules
* implemented in Mobile Safari on iPhone
*
* The TouchEvent module is a draft (18/08/200 that supports:
*
* touchstart
* touchmove
* touchend
* touchcancel
*
* The GestureEvent module is a draft (18/08/200
* that supports:
*
* gesturestart
* gesturechange
* gestureend
*
* The functions require support for try..catch, introduced
* in ECMA-262 ed3, JavaScript 1.4 and JScript 5.1.5010.
* Equates to Navigator 4.0 or later and IE 5.1 or later
* (http://pointedears.de/scripts/es-matrix/)
*
* If W3C DOM 2 Event document.createEvent is supported,
* return either true or false,
* otherwise return undefined.
*/
function touchSupported() {
if (document && document.createEvent) {
try {
document.createEvent('TouchEvent');
return true;
} catch (e) {
return false;
}
}
}

function gestureSupported() {
if (document && document.createEvent) {
try {
document.createEvent('GestureEvent');
return true;
} catch (e) {
return false;
}
}
}

/* Alternative hasTouch variable
*
* Example:
*
* if (hasTouches) {
* // assign touch and gesture events
* }
*/
var hasTouch = (function(){
if (document && document.createEvent) {
try {
document.createEvent('GestureEvent');
document.createEvent('TouchEvent');
return true;
} catch (e) {
return false;
}
}
})();
</script>
</head>
<body>
<div>
<button onclick="
alert('TouchEvent supported: ' + touchSupported());
">Touch supported</button>
<button onclick="
alert('GestureEvent supported: ' + gestureSupported());
">Gesture supported</button>
<button onclick="
alert('Touch and gestures supported: ' + hasTouch);
">Touch and gestures supported</button>
</div>
</body>
</html>


--
Rob
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Detecting mime types smcardle@smcardle.com Java 1 09-23-2007 07:57 AM
Detecting the opening of file types tazmaster2@gmail.com Java 1 05-07-2007 12:25 AM
detecting variable types Jay Python 15 09-25-2004 10:19 PM
detecting basic types Lasse Skyum C++ 6 12-24-2003 09:43 AM
Detecting document types Chris Java 0 11-24-2003 03:05 AM



Advertisments