In considering a design for the event iterator (allow devs to enumerate what 
events have been _added_ via addEventListener to a given object), I looked at 
too general approaches:

1) Defining a new collection on every object that supports the EventTarget 
interface
2) Defining a 'getNextEvent' function for every object that supports the 
EventTarget interface
3) Defining a function that returns a static/dynamic list of event handlers for 
a given object that supports the EventTarget interface

Ultimately, my design was to go with the 3rd option. Here's why:

Option 1 Pros:
* A collection property is easy to directly access via an object of interest
* A collection property is harmonious with other design decisions in the DOM 
(.childNodes, .attributes)

Option 1 Cons:
* There are many event 'types' that can be added to any given object as well as 
the characteristic of whether that listener is triggered on the capture/bubble 
phase, and a single collection merges all of these events in a way that is hard 
to split out individual types without the use of two keys (in other words, such 
a proposal would look a lot like the original HTML5-spec'd design for the 
globalStorage collection, except with two keys--unless we ignore the 
capture/bubble param).
* Requires a more rigid object or collection design than option 3.

Option 2 Pros:
* Supports the common incremental-access programming pattern (just get me the 
'next' defined event handler, if any).

Option 2 Cons:
* Does not support the random-access programming pattern (see discussion on 
.childElements collection [1])

Option 3 Pros:
* The 'retrieval function' approach has precedence in other DOM specs, such as 
getComputedStyle(...) and querySelector(...) where the returned collection can 
be either LIVE or not depending on need.
* The 'retrieval function' appraoch can support multiple parameters that can 
alter the collection that gets returned. This seemed like the most natural 
approach given that event listeners always have at least two parameters (event 
type string and isCapture bool).
* Provides random-access and iterative access through the returned collection.

Option 3 Cons:
* Not as convenient as a direct-access collection property

Without futher ado, here's my proposal for DOM L3 Events per-object enumerator 
(with a little help from the current Bindings [2] spec).

=========================
IDL Definition // Introduced in DOM Level 2:

// New in DOM Level 3:
typedef sequence<EventListener> EventListenerList;

interface EventTarget {
  void               addEventListener(in DOMString type,
                                      in EventListener listener,
                                      in boolean useCapture);
  void               removeEventListener(in DOMString type,
                                         in EventListener listener,
                                         in boolean useCapture);
  // Modified in DOM Level 3:
  boolean            dispatchEvent(in Event evt)
                                        raises(EventException,
                                               DOMException);
  // Introduced in DOM Level 3:
  void               addEventListenerNS(in DOMString namespaceURI,
                                        in DOMString type,
                                        in EventListener listener,
                                        in boolean useCapture);
  // Introduced in DOM Level 3:
  void               removeEventListenerNS(in DOMString namespaceURI,
                                           in DOMString type,
                                           in EventListener listener,
                                           in boolean useCapture);
  // Introduced in DOM Level 3:
  EventListenerList  getEventListeners(in DOMString typeFilter,
                                       in boolean useCaptureFilter);
  // Introduced in DOM Level 3:
  EventListenerList  getEventListenersNS(in DOMString namespaceURIFilter,
                                         in DOMString typeFilter,
                                         in boolean useCaptureFilter);
};

* getEventListeners[NS] - each parameter is allowed to be null.

* If null is provided for all parameters, then the sequence of EventListeners 
returned includes all event listeners added 1) from all namespaces, 2) for all 
event types, and 3) in all event phases (capture/bubble).

* Providing a non-null value for any of the parameters to these methods filters 
the set of returned Event Listeners in the sequence. For example:
[EventTarget].getEventListeners('click', null);
 returns all of the 'click' events added to the object for all event phases.

* The sequence of EventListeners returned from this API _must_ be in the order 
in which said event listeners will fire on the object (i.e., the order must be 
[capture events first sorted in order in which they will be fired, then bubble 
events sorted in the order in which they will fire).

================
Travis Leithead - OM Program Manager - Internet Explorer

[1] http://lists.w3.org/Archives/Public/public-webapi/2008Apr/0001.html
[2] 
http://dev.w3.org/cvsweb/~checkout~/2006/webapi/Binding4DOM/Overview.html?rev=1.66&content-type=text/html;%20charset=iso-8859-1



Reply via email to