© Copyright 2003 Opera Software.
This specification describes a mechanism for allowing servers to dispatch DOM events into documents that expect it.
This document currently has no official standing within the W3C at all. It is the result of loose collaboration between interested parties in private e-mail. To become involved in the development of this document, please send comments to ian@hixie.ch. Your input will be taken into consideration.
This is a working draft and may therefore be updated, replaced or rendered obsolete by other documents at any time. It is inappropriate to use Working Drafts as reference material or to cite them as other than "work in progress".
This draft may contain namespaces that use the uuid:
URI
scheme. These are temporary and will be changed before this specification
is ready to be implemented.
To find the latest version of this working draft, please follow the "Latest version" link above.
To specify an event source in an HTML document authors use a new (empty)
element event-source
, with an
attribute src=""
that takes a URI to open as a stream and, if
the data found at that URI is of the appropriate type, treat as an event
source.
The event-source
element may
also have an onevent=""
attribute. If present, the attribute
is treated as script representing an event handler registered as
non-capture listener of events with name event
and the
namespace uuid:755e2d2d-a836-4539-83f4-16b51156341f
or null,
that are targetted at or bubble through the element.
When an event-source
element
has a src
attribute set, the UA should fetch the resource
indicated by the attribute's value. If the resource has the type
application/x-dom-event-stream
, then it is processed line by
line as described below.
Since connections established to remote servers for such resources are expected to be long-lived, UAs should ensure that appropriate buffering is used. In particular, while line buffering may be safe if lines are defined to end with a single U+000A character, block buffering or line buffering with different expected line endings can cause delays in event dispatch.
In general, the semantics of the transport protocol specified by the
"src" attribute must be followed. Clients should re-open event-source
connections that get closed
after a short interval (such as 5 seconds), unless they were closed due to
problems that aren't expected to be resolved.
DNS errors should be considered fatal, and cause the user agent to not open any connection for the event-source.
HTTP 200 OK responses that have a Content-Type other than
application/x-dom-event-stream
should be ignored and should
prevent the user agent from reopening the connection for that
event-source. HTTP 200 OK responses with the right MIME type, however,
should, when closed, be reopened after a small delay.
HTTP 201 Created, 202 Accepted, 203 Non-Authoritative Information, and 206 Partial Content responses should be treated like HTTP 200 OK responses for the purposes of reopening event-source connections. They are, however, likely to indicate an error has occurred somewhere and may cause the user agent to emit a warning.
HTTP 204 No Content, and 205 Reset Content responses should be treated as if they were 200 OK responses with the right MIME type but no content, and should therefore should cause the user agent to reopen the connection after a short delay.
HTTP 300 Multiple Choices responses should be handled automatically if possible (treating the responses as if they were 302 Moved Permanently responses pointing to the appropriate resource), and otherwise treated as HTTP 404 responses.
HTTP 301 Moved Permanently responses should cause the user agent to use the server specified URI instead of the one specified in the event-source's "src" attribute for future connections.
HTTP 302 Found, 303 See Other, and 307 Temporary Redirect responses should cause the user agent to use the server specified URI instead of the one specified in the event-source's "src" attribute for the next connection, but if the user agent needs to reopen the connection at a later point, it should once again start from the "src" attribute (or the last URI given by a 301 Moved Permanently response in complicated cases where such responses are chained).
HTTP 304 Not Modified responses should be handled like HTTP 200 OK responses, with the content coming from the user agent cache.
HTTP 305 Use Proxy, HTTP 401 Unauthorized, and 407 Proxy Authentication Required should be treated transparently as for any other subresource.
HTTP 400 Bad Request, 403 Forbidden, 404 Not Found, 405 Method Not Allowed, 406 Not Acceptable, 408 Request Timeout, 409 Conflict, 410 Gone, 411 Length Required, 412 Precondition Failed, 413 Request Entity Too Large, 414 Request-URI Too Long, 415 Unsupported Media Type, 416 Requested Range Not Satisfiable, 417 Expectation Failed, 500 Internal Server Error, 501 Not Implemented, 502 Bad Gateway, 503 Service Unavailable, 504 Gateway Timeout, and 505 HTTP Version Not Supported responses, and any other HTTP response code not listed here, should cause the user agent to stop trying to process this event-source element.
The event stream MIME type is
application/x-dom-event-stream
.
The event stream is always be encoded as UTF-8. Line are always be terminated by a single U+000A line feed character.
The event stream format is (in pseudo-BNF):
<stream> ::= <event>* <event> ::= [ <comment> | <field> ]+ <newline> <comment> ::= ';' <data> <newline> <field> ::= <name> [ ':' <space>? <data> ]? <newline> <name> ::= one or more UNICODE characters other than ':' and U+000A <data> ::= zero or more UNICODE characters other than U+000A <space> ::= a single U+0020 character (' ') <newline> ::= a single U+000A character
The stream is parsed by reading everything line by line, in blocks separated by blank lines (blank lines are those consisting of just a single lone line feed character). Comment lines (those starting with the character ';' not proceeded by any other characters) are ignored.
For each non-blank, non-comment line, the field name is first taken. This is everything on the line up to but not including the first colon (':') or the line feed, whichever comes first. Then, if there was a colon, the data for that line is taken. This is everything after the colon, ignoring a single space after the colon if there is one, up to the end of the line. If there was no colon the data is the empty string.
Examples:
Field name: Field data
This is a blank field
1. These two lines: have the same data 2. These two lines:have the same data
1. But these two lines: do not 2. But these two lines: do not
If a field name occurs multiple times, the data values for those lines are concatenated with a newline between them.
For example, the following:
Test: Line 1 Foo: Bar Test: Line 2
...is treated as having two fields, one called Test
with
the value Line 1\nLine 2
(where \n
represents a
newline), and one called Foo
with the value
Bar
.
(Since any random stream of characters matches the above format, there is no need to define any error handling.)
Once the fields have been parsed, they are interpreted as follows (these are case sensitive exact comparisons):
Event
is the name of the event. For example,
load
, DOMActivate
, updateTicker
.
Namespace
is the DOM3 namespace for the event. For normal
DOM events this would be http://www.w3.org/2001/xml-events
.
If it isn't specified the event namespace is null.
Class
is the interface used for the event, for instance
Event
, UIEvent
, MutationEvent
,
KeyboardEvent
, etc. If it is not specified it is defaulted
based on the event name as follows:
If Namespace
is
http://www.w3.org/2001/xml-events
or null and the
Event
field exactly matches one of the events specified
by DOM3 Events in section 1.4.2 "Complete list of event types", then
the Class defaults to the interface relevant for that event type.
For example:
Event: click
...would cause Class
to be treated as
MouseEvent
.
If Namespace
is
uuid:755e2d2d-a836-4539-83f4-16b51156341f
or null and the
Event
doesn't match any of the known events, then the
RemoteEvent
interface
(described below) is used.
Otherwise, if the UA doesn't have special knowledge of which class
to use for the given event in the given namespace, then the
Event
interface is used.
Bubbles
specifies whether the event is to bubble. If it
is specified and has the value No
, the event does not
bubble. If it is specified and has any other value (including
no
or No\n
) then the event bubbles. If it is
not specified it is defaulted based on the event name as follows:
If Namespace
is
http://www.w3.org/2001/xml-events
or null and the
Event
field exactly matches one of the events specified
by DOM3 Events in section
1.4.2 "Complete list of event types", then whether the event
bubbles depends on whether the DOM3 Events spec specifies that that
event should bubble or not.
For example:
Event: load
...would cause Bubbles
to be treated as
No
.
Otherwise, if the UA doesn't have special knowledge of which class to use for the given event in the given namespace, then the event bubbles.
Cancelable
specifies whether the event may have its
default action prevented. If it is specified and has the value
No
, the event may not have its default action prevented. If
it is specified and has any other value (including no
or
No\n
) then the event may be cancelled. If it is not
specified it is defaulted based on the event name as follows:
If Namespace
is
http://www.w3.org/2001/xml-events
or null and the
Event
field exactly matches one of the events specified
by DOM3 Events in section
1.4.2 "Complete list of event types", then whether the event is
cancelable depends on whether the DOM3 Events spec specifies that that
event should be cancelable or not.
For example:
Event: load
...would cause Cancelable
to be treated as
No
.
Otherwise, if the UA doesn't have special knowledge of which class to use for the given event in the given namespace, then the event may be cancelled.
Target
is the element that the event is to be dispatched
on. If its value starts with a #
character then the
remainder of the value represents an ID, and the event must be
dispatched on the same node as would be obtained by the getElementById()
method on the ownerDocument of the event-source element responsible for
the event being dispatched.
For example,
Target: #test
...would target the element with ID test
.
If the value does not start with a #
but has the literal
value Document
, then the event is dispatched at the
ownerDocument
of the event-source
element responsible for
the event being dispatched.
Otherwise, the event is dispatched at the event-source
element itself.
Other fields depend on the interface specified (or possibly implied)
by the Class
field. If the specified interface has an
attribute that exactly matches the name of the field, and the value of
the field can be converted (using the type conversions defined in
ECMAScript) to the type of the attribute, then it must be used. Any
attributes (other than the Event
interface attributes) that
do not have matching fields are initialised to zero, null, false, or the
empty string.
For example:
; ...some other fields... Class: MouseEvent button: 2
...would result in a MouseEvent event that had button
set to 2
but screenX
, screenY
,
etc, set to 0, false, or null as appropriate.
If a field does not match any of the attributes on the event, it is ignored.
Once a blank line is reached, an event of the appropriate type is synthesized and dispatched to the appropriate node as described by the fields above. No event is dispatched until a blank line has been received.
The RemoteEvent interface is defined as follows:
interface RemoteEvent : Event { readonly attribute DOMString data; void initRemoteEvent(in DOMString typeArg, in boolean canBubbleArg, in boolean cancelableArg, in DOMString dataArg); void initRemoteEventNS(in DOMString namespaceURI, in DOMString type, in boolean canBubbleArg, in boolean cancelableArg, in DOMString dataArg); };
Events that use the RemoteEvent interface never have any default action associated with them.
The following event description, once followed by a blank line:
Event: stock change data: YHOO data: -2 data: 10
...would cause an event stock change
with the interface
RemoteEvent
to be dispatched on
the event-source
element, which
would then bubble up the DOM, and whose data
attribute would
contain the string YHOO\n-2\n10
(where \n
again
represents a newline).
This could be used as follows:
<event-source src="http://stocks.example.com/ticker.php" id="stock"> <script type="text/javascript"> document.getElementById('stock').addEventListener('stock change', function () { var data = event.data.split('\n'); updateStocks(data[0], data[1], data[2]); }, false); </script>
...where updateStocks is a function defined as:
function updateStocks(symbol, delta, value) { ... }
...or some such.
Thanks to Tom Pike and Joshua Randall for their substantial comments.