Last call comments on DOM3 Events

1.1 Overview

Considering this passage:
"The DOM Level 3 Event module is backward compatible with the DOM Level 2
Events [DOM Level 2 Events] module, i.e. a DOM Level 3 Events implementation
who returns true for "Events" with the version number "3.0" must also return
true for this feature when the version number is "2.0", "" or, null."

'a DOM Level 3 Events implementation who returns true for "Events" with the
version number "3.0" must also return true for this feature when the version
number is "2.0", "" or, null."' => a DOM Level 3 Events implementation where
hasFeature("Events", "3.0") returns true must also return true when the
version number is "2.0", "" or, null.

(This text occurs often, so this comment applies to all occurrences)

However, is this really a definition of "backwards compatible"? My
definition of backwards compatible is the other way round: if version N has
a feature then version N+1 has it too, but not the other way round. If every
feature in version N+1 is also in version N, then version N+1 must only fix
errors, and have no new functionality.

1.1.1 Terminology
"The process by which an event can be handled by one of the event's target's
ancestors before being handled by the event's target." => The process by
which an event can be handled by one of the event target's ancestors before
being handled by the event target.

"Bubbling
The process by which an event propagates upward through its ancestors after
being handled by the event's target.": Make this the mirror of the
definition for capturing:
The process by which an event can be handled by one of the event target's
ancestors after being handled by the event target.

Shouldn't "event target" be defined here?

1.1.2 XML Namespaces
Delete "as proposed by XML Events"

"associated to a namespace" => associated with a namespace

"Note that because the DOM does no lexical checking, the empty string will
be treated as a real namespace URI in DOM Level 2 Events methods." Shouldn't
that be "Level 3"? I don't understand this sentence, because I don't
understand what "does no lexical checking" means.

"Issue XMLEvents-1:
XML Events renamed DOMFocusIn, DOMFocusOut, and DOMActivate."
Fixed. We went back to your naming.

"Issue XMLEvents-2:
XML Events is based on DOM Level 2 Events, not DOM Level 3 Events."
This is still an issue. We need to make sure that we can properly handle
DOM3 and DOM2 with the same markup. i.e. we want

    <ev:listener event="xforms:recalculate" .../>

to behave the same on DOM2 and 3 and

    <ev:listener event="whatever" .../>

similarly.

The second one is easy I think. The first one is hard, which is why we don't
mention it in the most recent XML Events.
(http://www.w3.org/MarkUp/Group/2002/WD-xml-events-20020722/). Ideas?

"For instance, removeEventListenerNS remove the event that
addEventListenerNS add.": removes

"all event listener that match the type": listeners

1.2 Description of event flow

This is *extremely* difficult to read and understand. I think there are a
number of reasons:

    - "EventTarget" and "event target" are different concepts. The confusion
is so great that I think the text uses "EventTarget" in several places where
"event target" is actually meant, and vice versa. For instance "It can be
handled locally at the EventTarget level or centrally from an EventTarget
higher in the document tree." I believe that if you replace "EventTarget
level" with "event target" that this sentence actually becomes
understandable! I realise that this mess is now hard to undo, since the type
EventTarget exists, as does the attribute 'target', but on the other hand,
you don't have to let it show through in this text! Why not refer to 'event
nodes' which is any node in the tree you can hang a listener on (as
represented by the type EventTarget), and 'event target' which is the event
node that the event has been dispatched to?

    - The description does not follow the actual flow, but jumps around,
making it hard to follow.

    - Concepts have not been properly factored out. For instance, according
to the text, EventListeners can only call stopPropagation during capture and
bubbling, but not on the target itself. I'm sure that this is not intended.
stopPropagation should be a separate section like cancellation is, to avoid
this sort of mistake.

    - Parts of the description are defined in terms of things that are never
defined. For instance "Events which are designated as bubbling will
initially proceed with the same event flow as non-bubbling events. " though
nowhere is defined what the event flow is for non-bubbling events.

[[As a side issue: it would be great if you included text to event designers
on how to determine if an event should bubble or not, or be cancelable or
not. I noticed in the Forms working group that there was a lot of
brain-aching going on trying to work it out. You'll probably say "but that's
simple: ....", and that's exactly why you should write it down!]]

So as a conclusion I would respectfully ask that this section be rewritten,
along these lines:

<<<<
    There are two types of event: bubbling and non-bubbling.

    An event is dispatched to a 'target' node, and travels through the tree
in three phases: capture, target and bubbling.

    All events first pass down the tree from the root to the direct parent
of the target in the phase called 'capture'.

    All events then pass through the target node itself.

    Finally, bubbling events then pass up the tree from the direct parent of
the target to the root of the tree in a phase called 'bubbling'.

    The route through the tree is determined before dispatch starts (so that
if the tree changes during the phases, the original tree is used). [[Is this
true? The current description is unclear, since 1.3.1 seems to suggest that
the bubbling route is determined after capture. I discuss this more later.]]

    Listeners can be attached to nodes, which are activated when an event
passes through the node. A listener can either listen for events that are in
the capture phase, or in both of the other two phases, on the basis of the
useCapture parameter.

    When an event passes through a node in a phase, any listeners attached
to that node that are listening for that event in that phase are activated.
It is not defined what order the listeners are activated.

    Any listener may call the stopPropagation method; if this happens, all
remaining listeners on the current node are activated, but after that all
remaining steps in the propagation of the event through the tree are not
carried out.

    Some events have a default action, which gets carried out [when??? I
couldn't work it out]. Any listener may call the preventDefault method for
an event: if the event is cancellable, and it has a default action, that
action is not performed.
>>>>

Now to handle some points in the existing description.

1.2 Description of event flow.
"It can be handled locally at the EventTarget level or centrally from an
EventTarget higher in the document tree. "=>It can be handled at the event
target or from an EventTarget higher in the document tree.

1.2.1 Event listeners activation
"Each event has an EventTarget toward which the event is directed by the DOM
implementation."=>Each event has an EventTarget toward which the event is
dispatched by the DOM implementation. (May as well use the correct term).

This section describes what happens at the target. It says that the order of
execution of handlers is undefined; however the order is undefined during
*all* phases, not only at the target.

As pointed out, both capturing and bubbling say that stopPropagation may be
called, but not here.

1.2.2 Event capture
"If no additional capturers exist and stopPropagation has not been called,
the event triggers the appropriate EventListeners on the target itself."
What does this sentence add that isn't already described. Because I don't
understand why this sentence is here, I fear I am missing something.

Paragraph beginning "Although event capture is similar to the delegation
based event model". Please mark this paragraph as a note. I'm not sure who
it is directed at, or who benefits from it. I would prefer it be deleted. I
don't think it is normative.

1.2.4 Event cancellation
"Some events are specified as cancelable. For these events, the DOM
implementation generally has a default action associated with the event."
What does 'generally' mean here. Which events that are cancellable do not
have a default action?

"An example of this is a hyperlink in a Web browser. When the user clicks on
the hyperlink the default action is generally to activate that hyperlink.
Before invoking a default action, the implementation must check for all
event listeners registered to receive the event and dispatch the event to
those listeners."

Sneaky! This is a change from DOM2! DOM2 doesn't define when a default
action gets invoked. Suppose an implementation implements default actions as
a special class of handler on a node, that get executed after all
user-defined handlers on that node (which is perfectly allowable according
to DOM2.) All of a sudden those implementations will break for DOM3. So this
is a non-compatible change.

"This implies that those event listeners can be registered on the
EventTarget, or on the capture or bubbling phases. " I think 'event target'
is meant here, not EventTarget.

Part of the problem is that 'default actions' are so mysterious and
undefined, and only really appear here.

Proposal: make default actions a first class citizen. The advantage would be
that you could make a completely generic event processor, without any
knowledge of how default actions work:

    - in 1.4 add a method, or a parameter to initEvent to register a default
action for an event
    - define that the default action gets called after
capture/target/bubbling, with the event as parameter. The default action can
then use that information to decide how to react.

1.2.5 EventListener Grouping.

I couldn't understand this section at all. What is event flow in a group? It
is not defined anywhere. This needs a rewrite or some examples.

1.3.1. Event registration interfaces: Interface EventTarget: Method
addEventListener
"This method allows the registration of event listeners on the event
target." 'event target' should be 'EventTarget'.

"If an EventListener is added to an EventTarget while it is processing an
event, the EventListener will not be triggered by the current actions but
may be triggered during a later stage of event flow, such as the bubbling
phase." Too vague: "may"? What is a 'stage' of an event flow. Is it the same
as a phase? Do you mean to say that if you add it during capture, it *must*
be taken into account during bubbling? How about if I add it to a child
node: does it get processed then? 1.2.2 says "If modifications occur to the
tree during event processing, event flow will proceed based on the initial
state of the tree." but doesn't define what a change to the tree is. Is
adding a listener a change? By the way, you shouldn't say "an EventTarget
processes an event" but "an event gets processed at an EventTarget".

Parameter useCapture
"If true, useCapture indicates that the user wishes to initiate capture."
What does 'initiate capture' mean? I think you mean "if the user wants this
listener to be activated during the capture phase."

method addEventListenerNS, parameter evtGroup
Where are the semantics of groups defined?

method canTriggerNS
"This method allows the DOM application to know if an event listener,
attached to this EventTarget or one of its ancestors, will be triggered by
the specified event type during the dispatch of the event to this event
target or one of its descendants. "
The second 'event target' should be 'EventTarget'.
Can trigger during any phase? You should say so explicitely one way or the
other.

Hmm. I notice now that sometimes a listener is triggered, and sometimes
activated. Also sometimes an event is fired, and sometimes dispatched. Needs
cleaning up.

method dispatchEvent
"This method allows the dispatch of events into the implementations event mo
del.": implementation's

method isRegisteredHereNS
"event target"=>"EventTarget"

method removeEventListener
"If an EventListener is removed from an EventTarget while it is processing
an event, it will not be triggered by the current actions." Who is doing the
processing here: the EventListener or the EventTarget? Replace with "If an
EventListener is removed from an EventTarget while an event is being
processed there, it will not be triggered by the current actions."

method removeEventListenerNS
Same as above.
"independently of the event groups." whatever *that* means.

Interface EventListenerGroup
"When an event is dispatched, it is dispatched independently to each
EventListenerGroup."
What does *that* mean? An event is dispatched to a target, not to a group of
listeners.

Ooh. You're going to need to rewrite the introduction on event flow even
more. I just don't understand this! "In particular, the stopPropagation
method of the Event interface only stops propagation within an
EventListener's associated EventListenerGroup." Where's *that* described?

1.4 Basic Interfaces method initEvent
"This method may only be called before the Event has been dispatched via the
dispatchEvent method, though it may be called multiple times during that
phase if necessary." What does "that phase" mean? Does it mean "before the
event is ever dispatched"? Is it right (as this wording suggests) that you
can call initEvent as often as you want before dispatching it, but never
after. Or does it mean that it should be called at least once before
dispatch, but may be reinitialised later?

This text is used in many places, so I won't repeat this comment again, but
it applies to every occurrence.

"This method sets the type attribute to eventTypeArg, and localName and
namespaceURI to null. To initialize an event with a qualified name and
namespace URI, use the initEventNS method. "
Please unify this text with that for initEventNS, which uses a table.

"canBubbleArg of type boolean
Specifies whether or not the event can bubble. This parameter overrides the
intrinsic bubbling behavior of the event." Delete last sentence. (And
everywhere else the canBubbleArg parameter is defined)

"cancelableArg of type boolean
Specifies whether or not the event's default action can be prevented. This
parameter overrides the intrinsic cancelable behavior of the event." Delete
last sentence. (And everywhere else the cancelableArg parameter is defined)

method preventDefault
"If, during any stage of event flow, the preventDefault method is called the
event is canceled. Any default action associated with the event will not
occur." Replace with:
"If, during any stage of event flow, the preventDefault method is called any
default action associated with the event will not occur."

1.4.1 Event creation
I suspect that the reason I don't understand this section is because
'eventType' is different from 'Event.type' (in the Event interface). If I am
right, then please rename the concept called 'event type' here to something
else so I can understand it. Maybe 'event kind' or event sort'. I think a
new concept is being introduced here, but I don't understand it, and it
needs explaining.

1.5 Event module definitions
This whole section about naming recommends using prefixes to keep event
names distinct. But then what is the point of namespaces then? If you use
the namespace interfaces, then you should be able to call your events
anything you like. That's the whole point! Then different applications can
call similar events the same thing, and you still can identify which it is.

    xhtml:activate svg:activate xforms:activate might be three different
events for the same concept of activation. It would be daft to have to have
svg:SVGActivate.

1.5.1 DOMFocusIn//FocusOut
"Unlike the HTML event focus, DOMFocusIn can be applied to any focusable
EventTarget, not just FORM controls. " This is a tautology. You can only
focus on focusable elements. So what's a focusable element?

DOMActivate
"The activate event occurs when an element's default action is activated,
for instance, thru a MouseEvent click or a TextEvent textInput." Again,
tautological. s/thru/through/

1.5.2 Mouse Events

Attribute 'button'. My mouse has three buttons: two on top, and one for the
thumb. The thumb button is the leftmost, and therefore button zero according
to your definition, but not what you intend I'm sure.

1.5.3 Text events
This interface is horrible. Bound to a keyboard, and a fairly specific one
as far as I can see (No 'help' key? Oh, Windows keyboards don't have them!).
Why should text be bound to a keyboard? What about speech input? Or a
tablet? I think you need a logical text interface before a keyboard
interface. And why the inconsistencies between the keyboard in the mouse
events, and the one here?

1.5.5 HTML Event types

Why are these HTML specific? XHTML would like to use generic DOM events, so
using DOMFocusIn instead of focus, etc.

I propose a Device Module supporting: DOMLoaded, DOMUnloaded,
DOMLoadAborted, DOMLoadFailed,
a Viewport Module, supporting at least: DOMResized (surely with context
info), DOMScrolled (ditto).

I don't think we need a generic 'select' 'change' 'submit', since you can do
those with other means, nor 'focus' and 'blur'.

Steven Pemberton
For the HTML WG and the Forms WG

Received on Thursday, 1 August 2002 12:17:43 UTC